Shakespeare in a Toaster
- retrocomputing
- preservation
- reverse engineering
In 1995, a book called New and Improved Stupid Mac Tricks shipped with a floppy of novelty software. One of the programs on it was a sonnet generator whose splash screen announced, with total confidence, "Presenting… Shakespeare In A Toaster." You clicked a button and it produced fourteen lines of metrically plausible, rhyme-schemed nonsense. I was a kid. It was formative.
A while ago I went looking for it and found nothing. Not on Macintosh Garden, not on the Internet Archive, not in any shareware index I could search. As far as the visible internet is concerned, "Shakespeare" v1.0, © 1989–1991 by Bob Schumaker, does not exist. What did exist was my own Basilisk II disk image, where — it turned out — a copy had been sitting all along, installed from that book floppy into a folder literally named Fun.
This is a story about taking that 73 KB of resource fork apart, finding out it's much cleverer than it had any right to be, and porting it twice.
What's in the fork
The whole application is a single file with an empty data fork: everything lives in classic Mac resources. The lexicon is thirteen WORD resources named by metrical foot — FT_HF for stressed monosyllables, FT_IF for iambs, FT_TF for trochees, on up through five-syllable patterns, 2,011 words in all. One class, FT_TDF, contains exactly one word: BMW.
Every word carries a two-byte rhyme code, and this is where it gets good. The first byte is a vowel sound, the second is the final consonant sound — including cluster codes with example words baked into the app's own editing dialog: born/worn/porn, flipped/equipped/flapped, worse/hearse/coarse. So zoo is U plus "no consonant," zapped is short-A plus the pt cluster. Two words rhyme when their codes match. It's a phonetic rhyming dictionary — CMU-dict thinking, hand-entered, in 1989.
The composition engine, recovered from the 68k disassembly, is almost insultingly elegant. A line is an eleven-character stress template — literally the string 01010101010. The generator picks random words and accepts one only if its foot pattern string-matches the template at the current position. Stressed monosyllables landing on an off-beat get an unstressed connective glued in front, drawn from a weighted table: the 35%, no 21%, and 11%, with vowel-aware a/an selection. The rhyme scheme is another literal string, ABAB CDCD EFEF GG. When the lexicon can't produce a true rhyme, a line quietly restarts allowing assonance. Even-numbered lines must end stressed, so feminine endings only ever land where their rhyme partners can match them. Meter is enforced everywhere; grammar, nowhere. That's why the output sounds the way it does — "Castle the yolk humiliate no flux" scans.
The best feature was interactive: click a line to freeze it, then hit Rewrite, and the program recomposes only the unfrozen lines around your keepers. Iterative curation of computational poetry, in a windoid palette with a quill icon, before most people had email.
The credits
The About box scrolls credits that never made it to any catalog: "Rewritten for the Macintosh by Bob Schumaker. Overhauled by /rich $alz. Composer code written by Chris Wilbur. Thanks to Paul DuBois for the original TransSkel." That's Rich Salz of USENET and INN fame, and "rewritten for the Macintosh" strongly implies a pre-Mac original — probably Unix — that I haven't traced yet. If you know anything about it, my repo's issue tracker doubles as a tip line.
Porting it, twice
The decoded algorithm plus the extracted lexicon made a faithful port almost mechanical. There's now a Python TUI with the full 1989 feature set — freeze-and-rewrite, the wordlist editor, the dithered Droeshout portrait in the About box — and a web version that runs the whole engine client-side in 175 lines of JavaScript, dressed in System 7 clothes.
Fidelity turned out to be the fun part, because my memory kept filing corrections against the code. I remembered frozen lines showing in italics, not the selection bar I'd built — right. I remembered the sonnet being set in Geneva, not Chicago — right again, and when I said "I want to say 12 point," the disassembly answered back: TextFont(3); TextSize(12), sitting right there at offset 0x194. The web version now renders the actual Geneva 12 bitmap strike, pulled out of a System 7.5.5 suitcase from the same disk image, converted to a four-kilobyte pixel-outline webfont. (It ships under the name "Vevey," because the bitmap design is public domain but the name Geneva belongs to Apple.)
Some things I deliberately did not fix. Words repeat within a sonnet, because the original's no-repeat machinery only ever operated inside a single word slot. "The" can precede a verb, because nothing ever checked. Dactyls occupy two metrical positions with their third syllable slurred, because that's what the pattern table says. A port that cleaned any of this up would sound like a different, worse program.
Why bother
Software preservation usually means keeping bits. The bits here were nearly lost — one uncatalogued file on one privately owned disk image — but keeping them turned out to be the smaller half of the job. The interesting preservation was semantic: the rhyme-code phonetics, the connective percentages, the 9%-per-quatrain chance of a trochaic first foot. None of that is legible in a disk image. It took a disassembler, and it fits in a JSON file now, and anyone who wants to build Shakespeare In A Toaster for whatever platform comes next can do it from the spec.
Thirty-seven years on, the toaster still makes sonnets. Freeze the lines you like.