• Liquid code blocks in Jekyll posts

    This came up in the factorials post I did recently, and it was a bit maddening, so here’s a quick reference, so I remember it two years from now when it comes up again.

    Typical fenced code blocks in Jekyll (and any other Markdown situation) are surrounded with lines that are nothing but a triple backslash. (Your Markdown processor might also define a code language on the first line, so throwing a json on there might give you pretty formatting or color-coding, depending on your tools.) Example:

      "book": {
        "title": "Infinite Jest",
        "author": "David Foster Wallace"

    Here’s what that looks like in my editor:

    JSON code block

    Now let’s say you need to add an example of some code using the Liquid template language, as one might need to do when talking about Jekyll themes. When you get into your first full block of code with things like surrounding page.title with two curly brackets on either side of it, Jekyll’s going to start evaluating the code, even if it’s inside a block or a piece of inline code (hence me describing page.title with two curly brackets on either side of it instead of showing it). Liquid code takes precedence over any Markdown escaping.

    Liquid has a set of tags named raw and endraw to solve this. You can use these to surround a code block containing Liquid. The nesting is really touchy though, and there’s a good chance your editor’s preview won’t show it right.

    Two quick examples: First, you can put an inline example on a line. The output looks like this: {% assign n = 20 %}.

    Output of a fenced code block looks like this:

    {% assign result = 1 %}
    {{ result }}

    Here’s what these look like in my editor:

    Liquid code block

    Your mileage may vary; like I said, this is touchy. Make sure to fire up Jekyll locally and test it. Bad combinations will show up as errors in your server output.

  • New Headshot

    OK, new headshot for late 2021:

    Jonathan Konrath headshot

    Despite owning 167 cameras, I am not a photogenic person, and I do not like taking my own picture. But in the world of 100% remote work, most of the people in my company know me as the little icon next to my Slack chats or GitHub PRs. So, I had to do this.

    I’d advise people to pay someone to do this for them. But, pandemic. So here’s a few tips and observations on taking your own headshot.

    • Gear: Canon T6i, 18-55 kit lens, tripod, wired remote shutter.
    • Lighting: I shot against a blank wall perpendicular to west-facing windows in the afternoon. No flash on this one. I did use a fill flash on some of my attempts, but I liked the shadow of the natural light.
    • In any portrait, look at the eyes (or the glasses) and you can see how it’s lit. The square windows of my loft are visible in the upper corner of my glasses, and I think that looks okay. A direct ring light reflection, especially when it’s right on the iris, doesn’t look great.
    • If you have coke-bottle glasses like me, turn your head slightly. If you look head-on, that weird distortion field will be on both sides of your face. Here, it’s strategically off to the side.
    • if chins > 1 (sorry) try this: right before you pose, look down, then look up, stretch your neck a bit, then put it back down into position.
    • I’ve used a very careful crop of the crown of my head which is a great tip for men of a certain age who can’t wear a baseball cap in their headshot.
    • Another composition thing to keep in mind is that most places you use your picture, like Slack or a G-Suite account, will crop it into a circle icon. If your picture is way off-center, you might be nailing the golden ratio thing, but it’s going to crop weird.
    • If you don’t want a smiling picture, smile or laugh right before you trip the shutter. It takes some timing to get it so you’re somewhat between a smile and a scowl.
    • Use a black and white filter to look sophisticated (and worry less about skin tone).
    • Breathe. Relax. Take your time and take many shots. This was seriously the best of 65.

    I’d probably rate this picture a 3/5, but you should have seen the one I had on LinkedIn before this. Seriously, I went years with a carefully cropped image from a group photo of me and a half-dozen other people in a poorly-lit pizza parlor. I hope this one works better.

  • GitHub Pages Custom Domains

    I moved this site from Wordpress to GitHub pages a few months ago, and when I got to redirecting the domain, I punted and put an .htaccess file on the old site and 301’ed it over. That almost worked, but after each redirect happened, any old URLs were sent to jkonrath.github.io/, which broke all of my old links. I needed to properly point my hostname to the right place, and this was a bit maddening.

    Here’s what I did to get it to work. My domain is registered at Pair Domains, and my old site was running at Pair. This assumes you have created a GitHub account and a repo for your GitHub pages stuff, and have an address like I have jkonrath.github.io.

    Disclaimer: I’m not an IT professional, and you could mess up everything by listening to me. You probably shouldn’t listen to me about anything, let alone something involving data loss. You’ve been warned.

    The Pair part:

    1. Log in to the Pair ACC site. Back up the old WordPress site. Don’t forget to back up the database, too.
    2. Go to Domains and select the domain from the list.
    3. Select Delete Domain From Account.

      I only needed to do these three things because the domain was pointed at an IP and subdirectory of another host I run there. If you only registered a domain at Pair Domains and don’t host the site there, you don’t have to do this.

    4. Log in to the Pair Domains site, and select your domain name.
    5. Go to Domain Address Settings. This may be disabled by default; I had to accept terms and turn it on first.
    6. If you have Website Forwarding set, turn that off by deleting the forwarding URLs.
    7. From the Add New Record dropdown list, select CNAME (Parking).

      1. In the left side under Alias, put www.
      2. In the right, under Points To, put yourusername.github.io.
      3. Select Add Record.
    8. Go back to Add New Record, and select A (Round Robin).
    9. Under Host Name, put @ and under IP Addresses, put these four IP numbers:
    10. Select Add Record. You will now have a CNAME for www pointing to your GitHub Pages domain, and four A records pointing to the IP addresses above.

    Note: Double-check this nine times. The CNAME is www >> yourusername.github.io and there are four A records that are @ >> 185.199.x.y If you get the www and @ backwards, this won’t work.

    After you do this, you have to wait. It could be a minute; it could be a day. A good way to test it is whatsmydns.net, which shows how your changes have propagated around the world.

    Once that sorts itself out:

    1. Go to GitHub, and open the repo for your blog.
    2. Select Settings, then Pages. It will say your page is being hosted at yourusername.github.io. If it isn’t, you’ve got bigger problems. Sort those out first.
    3. Under Custom Domain, enter the custom domain and select Save. You’re putting in www.my-host-name.com. There’s no protocol in front of it (http://) but don’t forget the www.
    4. This will churn away and check the DNS for you. It will also kick off a request to Let’s Encrypt to make a certificate for free. You do not have to pay for anything at Pair or do any other legwork to get this done. The catch is that if you messed up the first part, or if GitHub’s feeling grumpy, that creation step will get botched, and you won’t get any helpful information, except it won’t work.
    5. Leave it alone for an hour or a day, and then you can select Enforce HTTPS and it will (eventually) enable HTTPS.

    On the last step: it may give you a byzantine error message, like “Unavailable for your site because a certificate has not yet been issued for your domain.” If that happens:

    1. Make sure your CNAME and A records on Pair Domains are correct.
    2. Wait a bit.
    3. Under Custom Domain in the GitHub Pages config, select Remove, then add it again. This will redo the request for a new certificate. Or not. I think I did it five times before it took.

    You may need to clear your browser cache or wait a bit more until this works, but test it with and without HTTPS and www.

  • Interview question - calculating a factorial

    When I was a tech writer, almost every time a developer interviewed me, they would inevitably ask me to whiteboard how to calculate the factorial of a number. When I moved to Northern California in 2008 and started interviewing at various Bay Area tech firms, I was seriously asked to do this exact problem at least twelve times in interviews with three companies.

    I thought of this recently after reading this, and thinking of the smart-aleck answers I never did give during interviews, like writing it in PostScript or COBOL.

    (BTW, a factorial is the product of all positive integers between 1 and n. It’s denoted as n! So 4! = 1 * 2 * 3 * 4 = 24.)


    The simple/obvious answer is doing it iteratively. In C:

    int factorial(int n)
      int i;
      int result=1;
      for (i=1; i<=n; i++){
        result = result * i;
      return result;

    Extra credit:

    • That should fail if you called it with a zero or a negative number.
    • There isn’t a main() that asks for a number and prints the result in a pretty way.
    • If you want to be cute, use the assignment operator result *= i instead of result = result * i and save nine keystrokes.


    They won’t always expect this from a writer who doesn’t regularly code, but here’s the other way to do it:

    int factorial(int n)
      if (n == 0)
        return 1;
      return n * factorial(n - 1);

    You can make this way more incomprehensible with the ternary operator:

    int factorial(int n)
      return(n==1||n==0) ? 1 : n*(factorial(n-1));



    I went to Indiana University at a time when the first three or four computer science classes were all taught in Scheme. I always wanted to whiteboard this as an answer:

    (define (factorial n)
      (cond ((equal? n 0) 1)
      (else (* n (factorial (- n 1))))))

    Extra credit: do it with tail recursion.


    This blog is in Jekyll, so maybe you’ve worked with Liquid templates before:

    {% assign n = 20 %}
    {% assign result = 1 %}
    {% for i in (1..n) %}
    {% assign result = result | times i %}
    {% endfor %}
    {{ result }}

    (Tip: if you have to put a Liquid template in a code block in Jekyll, look at the source of this page in GitHub. I’d explain, but delimiting the text in another example isn’t working.)


    APIs are the future (not speaking for my employer, of course) so maybe you want to use a REST API to do it:

    curl http://api.mathjs.org/v4/?expr=5!

    (Why use cURL though? There’s a much better way.)

    Standard libraries

    If they forget to qualify their question with “don’t use standard libraries” you can do this (Python):

    import math
    def factorial(x):
      print (math.factorial(x))

    Commodore BASIC 2.0

    Let’s take it back to the beginning:

    C64 BASIC factorial program


    I was trying to figure this out, but my SQL days are long behind me. You could use a recursive common table expression to create a table of n rows with each row containing the result of the previous row multiplied by the row number… or something.


    This is the point in my research where I had to give up and walk away for a bit. But if you had the right PDF CLI library, you could write a shell script that creates a one-page blank PDF, then iteratively merges copies of that template PDF onto a result PDF and count the number of pages at completion. There’s some magic number limit of objects in the PDF specification so they still work on 32-bit machines – eight million or so – which means this would break just past the factorial of 10.

    Actually, a lot of these would break after about 12, when you’d hit INT_MAX. There’s a way to do bigger numbers by creating an array of the number of digits you want to calculate, then writing a multiply function that does all of the carrying when each spot in the array goes past 9, etc. If you really want to push it, use a linked list instead of an array so you won’t waste any space. This probably won’t fit on one whiteboard.


    Oh, here it is in PostScript (I don’t know PostScript anymore; I borrowed it from here…)

    /factorial { 1 dict begin
      /n exch def
      n 0 eq {
        n n 1 sub factorial mul
      } ifelse
    end } def

    (The serious answer to all of this, if you’re a developer tasked with interviewing a tech writer, is to ask them about their problem-solving methodology, and how they figure things out when they don’t know the answer. People who have to write a code sample every other month won’t know off the top of their head how to reverse a linked list. They should be able to talk you through a difficult problem they had to solve once, though. It’s probably a cross-functional review, right? Test their soft skills, not their ability to memorize. Just my opinion.)

  • Atom as a Markdown Editor

    Part of this switch to Jekyll I mentioned previously is that I now edit this site in Markdown instead of WordPress. The great thing about Markdown is you can theoretically edit it in anything; you could even use Notepad or TextEdit or even the DOS Edlin editor to make a Markdown file. But you probably want something that adds some conveniences, like a few key bindings to save some time typing, a preview pane, and the ability to search and replace multiple files.

    When I first started using Markdown at work in 2015, I looked for a good editor that would do all of this, but never entirely found it. I stumbled through trying to set up Notepad++ like an IDE (I was stuck on a Windows machine), and I almost considered setting up Eclipse as a Markdown editor, but then I remembered it wasn’t 2003.

    I eventually settled on using Atom, which is a text editor-slash-IDE released by GitHub. It’s free, open-source, and customizable, with a lot of optional packages that are easy to add.

    Here’s what I did to set up Atom for my Markdown editing needs:

    • Not part of Atom per se, but life is much easier when I’m also using GitHub Desktop along with it. It makes it much easier to handle git commits/pushes/merges/branches. Atom does have its own git integration down in the lower right corner, where you see your current branch, do a quick fetch, and see PR review comments.

    • First thing I do is change the theme, because I can’t deal with dark mode (sorry). Go to Preferences > Settings > Themes and pick something; I usually go with One Light, but there are many options.

    • Then go to Preferences > Settings > Install and grab the following:

      • language-markdown - adds grammar support for MD files.
      • markdown-writer - adds more MD writing features.
      • markdown-preview-enhanced - there are a few previewers out there, but this one seems to work best for me. I had problems with markdown-preview handling Jekyll files; maybe that’s fixed now?
    • Go to Preferences > Settings > Packages and go to the settings for the spell-check package. In the Grammars section, add text.md.

    • If you File > Open to the directory of your project, it opens it with the hierarchy shown in the left sidebar, and you can then click around in that to open various files.

    I’ve been using this setup daily for a while now at work. But now everyone’s using Visual Studio Code, so maybe I need to switch.