This is the happy result of some frustration and study, trial and error. I suspect it's too early to declare victory, but initial indications look promising.
I attend a weekly Zoom meet-up of Tinderbox users, and I enjoy the social aspect as well as maybe learning something now and then. Most of the time, the techniques being demonstrated don't really relate to anything I'm doing with Tinderbox, nevertheless, I'm impressed and entertained by watching them unfold.
In the decade or so that I've been maintaining the marmot, I haven't really taken much advantage of the automation frameworks afforded by Tinderbox, Action Code and Export Code, and now, AppleScript. Mostly I just use a bare minimum of fairly static Export Code, and a little bit of Action Code to call the weather stuff, set the various attributes for the permalinks and export files.
My biggest challenge in automating the marmot was in posting photos. Prior to the change, I basically did everything manually, albeit with a lot of "copy and paste" action. The Photos to Tinderbox AppleScript automates nearly every aspect of that now. The only real manual effort is entering the title and caption info, and then hitting the Sync button in Forklift.
It was a pretty fair amount of effort, because Photos didn't seem to allow export from AppleScript. You could do it with Automator, so I had to create an Automator application to call from the AppleScript, and you can't specify a file path for the export. It always exports to folder in the ~/Pictures directory, and it always appends a ".jpeg" file suffix to the export.
After Automator exports the photo, Hazel comes in an moves the image to the marmot's Tinderbox directory and changes the suffix from .jpeg to .JPG, which matches the file suffix for images from my Olympus cameras. Export Code creates the html necessary to display the image from the photo's filename, which is why I have to change ".jpeg" to ".JPG" or I get a missing image icon.
Anyway, that was a fair amount of work, but it works well and I'm happy with it.
But if I want to post a picture taken with my iPhone, then I have to do some manual intervention. The iPhone stores images in HEIC format with a .HEIC file suffix. I could set the iPhone to store images as jpegs, but HEIC is more space efficient and I like that. So the filename, from which the html is constructed, is the original filename from the camera, with .HEIC as the suffix. Photos exports as JPEG (or TIFF or PNG), so the filenames don't match after export. I can't construct the html from the filename attribute I sent over from Photos. I've had to go manually change the .HEIC in the html to .JPG, which is not a big deal, but it's enough friction to keep me from posting images from the phone very often.
This particular challenge is something I've never tried before, manipulating the value of an attribute and creating a new attribute as a result. I wanted to just extract everything left of the file type suffix and make a new attribute I just call "Photo." Then in the export code, I just put the ^ photo attribute in the html and append the ".JPG" in the html from the prototype.
But how do you manipulate attribute values in an note? Well, you do it with a Rule. Up until today, all the attributes I created with Action Code were part of an OnAdd action, which the monthly archive container applies when a new post is created, to every post. Since a photo post is a post, there's nothing wrong with all that code; but a photo post has attributes that only apply to photos, and it has it's own embedded html in the note's $Text, so it uses a different prototype as a post. So OnAdd wasn't really the appropriate way to go here.
Well, a note's "Rule" is the way you mess with attributes in only that note. Then I had to figure out how to get everything to the left of the file suffix. There are text operators you can use that involve regular expressions, none of which I have ever used before.
Taking a tip from Dave Winer, I asked ChatGPT, "What is the regular expression needed to extract the text of a filename before the file type suffix?"
This is the response:
=========
To extract the text of a filename before the file type suffix using a regular expression, you can use the following pattern:
```regex
^(.+?)(\.[^.]+)?$
```
Explanation:
- `^` asserts the start of the string.
- `(.+?)` captures one or more characters non-greedily (lazy matching) into a group.
- `(\.[^.]+)?` captures a dot followed by one or more non-dot characters into an optional group.
- `$` asserts the end of the string.
In this pattern, the first captured group will contain the filename without the file type suffix.
========
Not being willing to trust ChatGPT, I tested this in an app called RegExRx and it seemed to work. $1 was just the name minus the filetype suffix, which is what I wanted.
Throwing caution to the wind, I created a new Tinderbox file, created the relevant user attributes ($PhotoFilename and $Photo) and entered the following rule in a new note:
$Photo=$PhotoFilename.replace("^(.+?)(\.[^.]+)?$","$1")+".JPG";
(The +.JPG part I added later when things went sideways a bit.)
In the test note, I got just the part of the filename I wanted.
Then I tried it here. (I just noticed another thing I have to fix, but it doesn't interfere with exporting from Tinderbox.)
I originally tried to add the ".JPG" in the photo post's $Note text. That got all wonky and I don't really know why. Then I figured I'd try to do it in the Rule and that worked fine.
Now I have to test this with a regular photo from a "real" camera. There are usually unintended consequences and breakage. We shall see.
Originally posted at Nice Marmot 14:57 Wednesday, 12 July 2023