Yak-shaving my way to a big stack of crosswords

You might want to make a cocktail for this one, about a big part of a day in the life of a geek.

tl;dr Geeks always can find a harder way to do things.

So my HP laser printer has been getting more and more annoying with bugs, glitches, and bad output. The autofeeder stopped working years ago, with bogus paper jam errors, and the printer routinely puts itself into a coma instead of a wakeable sleep.

Fed up, and convinced I’d used the last of my toner cartridges, I tried using Claude (the politically preferable-to-ChatGPT AI agent) to confirm my research on which monochrome laser printer that is AirPrint compatible I should buy, and the answer was still Brother DCP-L2640DW, which has the advantage of not being HP. HP used to be the brand for so many things including printers, but in recent decades their products have had incredibly annoying UX, are cranky about 3rd party supplies, and come with tedious, useless tech support–and they don’t seem to be aware that consumers like Macs. Claude also confirmed that this is most cost-effective for medium- and high-volume printing, especially if you buy 3rd party high-capacity toner cartridges.

I then did some price-searching and placed my order.

Today while digging around in my office closet looking for something else, I found one last toner cartridge for the printer I want to banish, hiding in a stupid cranny. Because of course I did.

So clearly I need to do a shit-ton of printing and use this sucker up. That means it’s time to download and print another year’s supply of NYT crosswords from the archive. (I’ve long since finished all the big Sunday omnibus volumes.)

If you aren’t a crossword geek, you might not know that NYT crosswords are generally easiest on Mondays and get harder through the week, and then Sunday is about Thursday-hard but larger. Monday through Wednesday are so easy I just do them on the app when I’m bored, and Thursday through Sunday I prefer to do on paper, with a nice .03mm mechanical pencil and a Japanese plastic eraser while drinking my morning coffee. To complete your mental image of my lazy mornings, picture me in a recliner with Daża on my lap. She’s the perfect crossword lapdesk, at least until she decides to sit up, and it becomes a lot harder to make crossword progress.

As a NYT subscriber, I have access to the full archive of puzzles, so periodically I go download another few months’ worth of the Thursday through Sunday puzzles, in ink-saver mode, and print them out on the backsides of my stack of misprints and garbage and old junk. It’s kind of tedious, because each one requires three clicks, a command-click, a tab switch, and another click. Then I have to go to my Downloads folder, open the first one, open the left sidepanel to Thumbnails, and drag all the other ones for the month into the first one so that I can print them all at once instead of one at a time.

This quickly becomes annoying, so I start yak-shaving, which is programmer-speak for wasting hours, days, or potentially weeks to figure out a more elegant, more automated way to do it, and ideally also make you coffee while giving your pet yak a haircut. Why we call this yak-shaving is left as a search-engine exercise for the reader.

So I figure someone must have written some scripts to do this kind of thing, right?

There follows a lot of googling, downloading, installing, configuring, reconfiguring, googling, reinstalling, …lather, rinse, repeat… to get a handy tool called “NYT Crossword Downloader” which is on github at https://github.com/laurelmay/nyt-crossword-download?tab=readme-ov-file. I then need to install Chrome and an extension for extracting cookies, log into NYT from Chrome, run the extension, and move the file to the right place. Then I put together a command to print a single puzzle and get a series of errors that lead me to install a current version of Python, then more errors that lead me to reinstall Python using homebrew, which of course I should have just done in the first place, and then install a doodad called pyenv so that I can force my Python commands to use this new build instead of the built-in 3.9 build of Python. All this involves more googling to remind myself which shell I’m using (tcsh) and how to translate bash examples to tcsh, which of course I know but I do it just seldom enough that google is usually involved. Then I need to reinstall the requirements, which requires figuring out how to force pip to work with the current Python. Whatever pip is…

I do a LOT of scripting, mind you, but it’s usually the JMP Scripting Language or tcsh. I’ve never bothered to learn Python. I avoid Java as much as possible. I still mean to learn PERL one of these decades. So for me doing anything with someone else’s Python turns into a yak-shaving adventure like today’s.

And, well, holy cow! I just successfully ran a Terminal command to print a single puzzle! Hey, we’re only three hours in!

Crap. It also printed the solution on a second page. I don’t need that. If I get stuck (which is rare these days and usually involves pop culture references), I go see what Rex Parker has to say, because the answers I can’t figure out are typically answers I also won’t understand without some explanation, and it always makes me feel better when he calls out the Naticks and the OREOs and whatnot.

Found the command-line switch to turn that off.

OK, now we need to iterate this command over all the dates in a year that are Thu, Fri, Sat, or Sun. More googling, a bunch of trial and error, and I have a short script that first creates a dates.txt file with one correctly-formatted date per line matching those criteria. Then I replace the date argument in my command with `cat dates.txt`, test some more, and Bob is officially my uncle.

So it’s been four hours, and my crappy old HP printer is slogging away at a massive print job. Only 44 more puzzles to go. And then I replace "2020-01-01" in my batchPrint.sh with "2019-01-01" and do another year, etc., until this toner cartridge is dead.

If I were more clever, I would do some more googling, trialing, and erroring to figure out how to parameterize the starting date, how long to go from that date, and which days of the week. Then I would figure out how to skip the intermediate dates.txt file and pipe the dates directly into the command. I conceptually know how to do these things, but again I don’t shell script often enough to remember how actually to do it. I also don’t want my trialing and erroring to send me into a loop where I print a few thousand copies of an error message.

So, if anyone feels like shaving their yak, here’s what I’ve got so far. Run this from #! in BBEdit like I do, or save it in a file and figure out with your own yak how to run it from your Terminal.

#!/bin/tcsh

# install this and everything it needs and the horse it rode in on
# https://github.com/laurelmay/nyt-crossword-download?tab=readme-ov-file

# go where you installed it
cd ~/Downloads/crosswords/nyt-crossword-download-main

rm dates.txt # start fresh

foreach day (`seq 0 365`)  # do a whole year 
  set d = `date -j -v+${day}d -f "%Y-%m-%d" "2019-01-01" "+%Y-%m-%d %a"`  # replace start date
  if ("$d" =~ *Thu* || "$d" =~ *Fri* || "$d" =~ *Sat* || "$d" =~ *Sun*) then
    echo $d | awk '{print $1}' >> dates.txt
  endif
end

foreach date ("`cat dates.txt	`")
  ./download.py -p --no-solution -d $date --ink-saver 
end

And with that, my yak is officially bald and has a really bad case of razor-burn, and I have a year’s worth of Thu-Sun puzzles printed, and I’m about to start 2019. It’s only been four and a half hours.

Problem is, I’m almost out of paper and now I have to go to Costco.

Extra credit for smart-alecks: yes, I know there’s also ernstwi on github that has a flag for a particular work day, but that one only downloads, doesn’t print, and it doesn’t have options for getting the Inksaver version (which has grey squares instead of black squares), and I’m not sure what it does about solutions, etc., etc. I knew I could figure out how to iterate on a list of dates, and how to create a list of dates that are only Thu-Sun. I do not think I could figure out the other stuff in the same year I started trying.

Finally, major shout-out and thanks to Laurel May for doing the Python work so we didn’t have to.

Whoops, add another little while to write this all up, which requires remembering how to use the dreaded WordPress. It’s been a 7:31:00 yak-shaving adventure! Who else needs a martini and a hot tub, stat?

Oh. Also left as an exercise is duplexing. My method is to load the printer with a big stack of paper, print until it runs out, turn the printed stack upside down, and put it back in the paper loading thingy. Since this is a bit haphazard, I don’t end up with my puzzles in any particular sequence, but I also don’t really care. If you do, you’re gonna need a bigger yak.

And in conclusion: Damn toner cartridge.