42 Astounding Scripts

MacOS uses Perl, Python, AppleScript, and Automator and you can write scripts in all of these. Build a talking alarm. Roll dice. Preflight your social media comments. Play music and create ASCII art. Get your retro on and bring your Macintosh into the world of tomorrow with 42 Astoundingly Useful Scripts and Automations for the Macintosh!

Jerry Stratton

Simple code plus smart data is better than enough smart code to do the same job. — Eric S. Raymond (Declarative is greater than imperative)

The Soul Felt It’s Worth—Wednesday, December 20th, 2023
Weary Skybox: “The weary world rejoices” over a starfield.; Christmas music; Christmas carols; Hymns

Earlier this year I discovered the Brian Setzer Orchestra’s Boogie Woogie Christmas at a garage sale in Michigan. Their version of O Holy Night reminded me just how wonderful and inspiring a song O Holy Night is. And after a difficult year, how much it expresses the yearning and emptiness that celebrating Christmas both secularly and religiously can fill.

    • Long lay the world in sin and error pining,
    • Till He appeared and the soul felt its worth.

“A thrill of hope, the weary world rejoices…” Some Christmases we need the opportunity for rejoicing more than others.

O Holy Night (3.5 MB MP3 file)

View audio.

There are three verses, but in my experience, “O Holy Night” is almost always sung with only the first verse. Partly I suspect that’s because the second and third verses don’t scan very well, and in addition the third verse’s mention of slavery is viewed as somewhat outdated. The line wasn’t initially directed at American slavery: the original lyrics were French. They were written in after the French revolution, in 1843; my guess is that the slaves in the lyrics almost certainly referred to French citizens, no longer slaves of the King and other royalty.

The lyrics were translated into English by Bostonian John Sullivan Dwight in 1855. Dwight’s translation is very loose, but the original third verse’s “Il voit un frère où n’était qu’un esclave…” tracks very closely with Dwight’s “for the slave is our brother”.

I can find no evidence that Dwight was an ardent or even occasional abolitionist. He was a music critic and magazine publisher. He did, apparently, include “the music of black Americans” in his magazine when submitted. The 1855 volumes of his magazine, if the Internet Archive’s OCR is to be trusted, contain no mention of “abolition” other than one about “the abolition of the mock auction system” in the selling of concert tickets and another about the “total abolition of hymn books”. The only mention of “negro” is in reference to music.

Padmath in Ventura—Wednesday, September 27th, 2023
macOS Ventura logo: Apple’s logo for macOS Ventura.; macOS Ventura

I apologize for putting this off for so long; I’ve been expecting to see more changes that need to be made in scripts after upgrading to Ventura, because this is hardly worth a post. But it could be very annoying if you’re relying on padmath.

Padmath stopped working after upgrading to Ventura. I noticed that very quickly—it’s one of my most commonly-used Services. But it’s a simple fix. The version of bc on Ventura now has an abs function. This means that abs is now a reserved word, and cannot be used to create a custom function.

Since the custom function was just a means of adding an abs function anyway, delete the lines that define the custom abs function and padmath will start working again.

[toggle code]

  • define abs(value) {
    • if (value < 0) {
      • return -value
    • } else {
      • return value
    • }
  • }

I haven’t yet noticed any other issues with using the scripts under Ventura.

Find all parent mailboxes in macOS Mail—Wednesday, September 6th, 2023
AppleScript Editor: Enable Script Menu: Enable the Script Menu in AppleScript Editor’s preferences.; AppleScript

Make sure Script Menu is enabled in Script Editor.

I am an information packrat; I never throw out emails, and have messages dating back to the last century. I manage this using hierarchical mailboxes to keep the archives from cluttering up my Mail window.

I have Rules set up to send various messages directly to the mailbox where they should be stored, and then Smart Mailboxes to display unread messages of various classifications: Unread Mail, Unread Mass Mails, Unread Spammy, and Unread Junk, each less critical than the previous.

In the past, it’s been easy enough to see where any message is stored. The macOS Mail app has acted like any other application on the Mac: documents (i.e., messages) could display the full path to the document by option-clicking the document’s title (i.e., the message’s subject) in the window’s title bar.

As far as I can tell, this is no longer possible. Mail has been moving away from a document-based model toward a flat, search-based model, and no longer makes it easy—or even possible—to find the full path to a viewed message. The immediate parent mailbox’s name is displayed in the sidebar, but the mailbox’s parent is nowhere to be found. So that I can see easily enough that the order I’m waiting on is in the eBay mailbox. But not that the eBay mailbox is in the Purchases mailbox of the Finances mailbox. The latter two are completely hidden.

Obviously, however, the Mail app itself knows where these messages are, and that information can be displayed using AppleScript.

[toggle code]

  • tell application "Mail"
    • set mailboxPaths to ""
    • repeat with currentMessage in (get selection)
      • set mailboxPath to ""
      • set messageMailbox to the mailbox of currentMessage
      • repeat while (exists name of messageMailbox)
        • set mailboxPath to the name of messageMailbox & ":" & mailboxPath
        • set messageMailbox to the container of messageMailbox
      • end repeat
      • set mailboxPaths to mailboxPaths & mailboxPath & return
    • end repeat
  • end tell
  • display dialog mailboxPaths buttons ("OK")
JXA and AppleScript compared via HyperCard—Wednesday, August 9th, 2023
Superhero stack opening card: Main “control panel” card for the Men & Supermen superhero character sheet HyperCard stack.; Men & Supermen; HyperCard

All this for a script that will be used no more than a handful of times, to restore long-replaced data from the nineties. It’s time to quote Douglas Adams again.

In A HyperCard Time Machine I wrote that I also seriously considered writing the script as a JavaScript (JXA) app. In fact, I did write the script as a JavaScript app. It was a toss-up to the end which version I was going to use, so they’re both fully-working versions.

One advantage the JXA version has is not requiring old-school, BASIC-style manipulation of strings to extract the current card number and the total card count from the window title. Instead of grabbing the location of the final slash, which required serious gymnastics in AppleScript, the JavaScript solution can use a regular expression that is both shorter and more reliable:

[toggle code]

  • titleRegex = new RegExp("^(.+[^ ])  *([1-9][0-9]*) *\/ *([1-9][0-9]*)$");
  • titleParts = titleRegex.exec(title);
  • filename = titleParts[1];
  • currentCard = titleParts[2];
  • totalCards = titleParts[3];

JXA also doesn’t use tell blocks. It places the application in a variable, and the things we want to tell it to do can be handled at any point without worrying about how a tell block affects the syntax. At the beginning of the app, I did:

  • app = Application.currentApplication();
  • app.includeStandardAdditions = true;
  • system = Application("System Events");

This gave me the current application and System Events. The current application is necessary for dialog with the user, which is why I’ve also included the Standard Additions on it. The Standard Additions include Display Dialog and Choose Folder.

Older posts