The earliest memory I have of ‘programming’ is in the early/mid 90s when my father brought home a computer from work. We could play games on it … so of course I took the spreadsheet program he used (LOTUS 123, did I date myself with that?) and tried to modify it to print out a helpful message for him. It … halfway worked? At least I could undo it so he could get back to work…

After that, I picked up programming for real in QBASIC (I still have a few of those programs lying around), got my own (junky) Linux desktop from my cousin, tried to learn VBasic (without a Windows machine), and eventually made it to high school… In college, I studied computer science and mathematics, mostly programming in Java/.NET, although with a bit of everything in the mix. A few of my oldest programming posts on this blog are from that time.

After that, on to grad school! Originally, I was going to study computational linguistics, but that fell through. Then programming languages (the school’s specialty). And finally I ended up studying censorship and computer security. That’s about where I am today!

But really, I still have a habit of doing a little bit of everything. Whatever seems interesting at the time!

Popular Github Repos


StackLang Part II: The Lexer

StackLang, part 2: lexing.

It’s quite often the simplest part of implementing a programming language (although parsers for s-expression based languages come close), but it’s still something that needs done. So here we go!


StackLang Part I: The Idea

I enjoy writing programming languages. Example: Tiny. Let’s do that again.

This time, StackLang:

  @[n fact]
  { n 1 - $fact fact n * }
  N 1 <= if
} @fact

5 $fact fact writeln

Bit of gibberish there, I suppose, but the goal is to write everything in a postfix/stack based model. So n 1 - $fact fact n * is equivalent to fact(fact, n - 1) * n in a more traditional language.

Over the next few posts, I hope to write up where I am thus far and what’s next.


Wildcard Let's Encrypt certificates with Nginx Proxy Manager and Cloudflare

Another quick snippet that I figured out this weekend. It’s not hard, but it’s something that I really wanted to do and had to look up where it was, so perhaps it will help you.

Problem statement:

I run a bunch of local services in my network. They aren’t exposed publicly (I use Wireguard to access them when out and about), so I really don’t need HTTPS. But (rightfully) a number of services behave better when they’re behind HTTPS + if there’s ever a service that’s running amuck (Internet of Things devices?) that’s listening, I don’t want them to see anything.


Option 1: Use Nginx Proxy Manager to request certificates for each subdomain. It works quickly and well. Problem: All certificates are published to Certificate Transparency Logs. I don’t immediately mind exposing what I’m running… but I’d still rather now.

Option 2: Set up wildcard certificates. This requires integration with your DNS provider (since wildcards need a DNS challenge, not TCP).

Of course (based on the title), we’re going with option 2. 😄


Automated transcripts from video with Whisper(.cpp)

I tend to be something of a digital packrat. If there’s interesting data somewhere, I’ll collect it just in case I want to do something with it.

Helpful? Usually not. But it does lead to some interesting scripts.

In this case, I have a site that hosts videos. I want to download those videos and get a text based transcription of them. With new AI tools, that shouldn’t be hard at all. Let’s give it a try!


Keyboard Chords with Hammerspoon

I love keyboard shortcuts. The less I have to switch between keyboard and mouse, the more efficient I (at least feel I) can be!

Problem statement

But there are only so many unique combinations of keys on a standard keyboard. Assume 26 letters, 10 digits, and (for now) 20 other characters, along with 4 ‘modifier’ keys (⌘ ⌃ ⌥ ⇧) that you can use in any combination of one or more. So 26 * 10 * 20 * (2^4 - 1) = 78,000 . Like I said. Limited. 😄

But we can do better!

Enter the Hammerspoon hs.hotkey.modal module!


Genuary 2023.31: Break a previous image


Spend a month making one beautiful thing per day, given a bunch of prompts. A month late, but as they say, ’the second best time is now'.

Let’s do it!

31) Deliberately break one of your previous images, take one of your previous works and ruin it. Alternatively, remix one of your previous works.


Genuary 2023.30: Minimalism

Genuary! Spend a month making one beautiful thing per day, given a bunch of prompts. A month late, but as they say, ’the second best time is now'. Let’s do it! 30) Minimalism Demo Script let gui; let params = { lineWidth: 10, minWidth: 50, maxWidth: 100, maxWidthMax: 400, minHeight: 50, maxHeight: 100, maxHeightMax: 400, colorChance: 0.1, colorChanceMin: 0, colorChanceMax: 1, colorChanceStep: 0.01, } let box; let colors = [ "red", "blue", "yellow", ] function setup() { createCanvas(400, 400); box = { x: -params.