Clean code is its own best explanation and good typing should keep the code itself available to the eye. — John M. Nevison (The Little Book of BASIC Style)
- Padmath in Ventura—Wednesday, September 27th, 2023
-
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 anabs
function. This means thatabs
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 customabs
function and padmath will start working again.[toggle code]
-
define abs(value) {
-
if (value < 0) {
- return -value
-
} else {
- return value
- }
-
if (value < 0) {
- }
I haven’t yet noticed any other issues with using the scripts under Ventura.
-
define abs(value) {
- Find all parent mailboxes in macOS Mail—Wednesday, September 6th, 2023
-
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")
-
tell application "Mail"
- JXA and AppleScript compared via HyperCard—Wednesday, August 9th, 2023
-
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.
- A HyperCard Time Machine—Wednesday, July 19th, 2023
-
This was a tool for an early role-playing game. And looks it.
My second programming job out of college started as a HyperCard stack. HyperCard was an amazing tool not just for programmers, however, but especially for the weekend programmer or even the weekend non-programmer. It didn’t require any programming to get started. Just put some text placeholders on a background card, some buttons, maybe add a pre-created action to a button such as “move to next card”, and you had a very simple visually-oriented application that responded in a manner customized for you and your data.
There were a lot of non-programmers who used HyperCard and graduated to weekend programming. Because after you wrote your text or placed your graphics or added a button with a standard action, if you wanted to add code to that object, you could. You might start with slinging messages from object to object, or performing simple math on one of the text placeholders.
HyperTalk was not object-oriented in the sense that programmers mean when they talk about object-oriented programming. But it was object-oriented in the sense that programmers explain object-oriented programming to non-programmers. Every object on the screen could contain code that responded to specific actions. Each card could respond to keystrokes. A text box could respond to typing. Cards, text boxes, buttons, and images could respond to mouse actions. Keystrokes, mouse actions, and custom functions were all messages. And each object could send messages to other objects.
HyperCard was often used for databases; the card metaphor was especially apt for that. For example, I had a database of superheroes and supervillains in the Men & Supermen superhero role-playing game.
The game used meters, but clicking on the word “Height” on the character sheet would calculate and then display the character’s height in feet and inches: