Regrettable Adventures in AppleScript: Publishing from iA Writer
Now that I’m actually posting to this blog for the first time in who-knows-how-long, I decided to put some time into removing the friction from this process. Since I last posted here, my writing process has evolved into something like this:
- When I have an idea I want to write about, I’ll jot down a few quick notes in Notes.app on my iPhone
- When I’m ready to flesh that out, I’ll write up an outline in OmniOutliner Pro or OmniOutliner for iOS.
- When I’m ready to write the actual post, I open iA Writer in split screen with OmniOutliner and turn that outline into beautiful, deeply amateurish words.
- I take the Markdown file from iA Writer and add it to my blog’s git repo.
So this morning as I was working on a new post in iA Writer, and continually copying it into my blog’s repo to preview how it would look on the site, I thought “why don’t I automate this?” I’ve barely dabbled in Mac automation, but it seemed like AppleScript was the tool for the job. Anyway, an hour or so later, after tearing my hair out over AppleScript’s not-quite-english syntax, I ended up with this:
on date_to_iso(dt)
set {year:y, month:m, day:d} to dt
set y to text 2 through -1 of ((y + 10000) as text)
set m to text 2 through -1 of ((m + 100) as text)
set d to text 2 through -1 of ((d + 100) as text)
return y & "-" & m & "-" & d
end date_to_iso
set destination to "Macintosh HD:Users:rpowell:Projects:rpowelll.github.io:_posts"
set dt to current date
set iso_dt to date_to_iso(dt)
tell application "iA Writer"
set source to file of document 1
end tell
tell application "Finder"
set copiedPost to duplicate file source to folder destination with replacing
set slug to name of copiedPost
set ext to name extension of copiedPost
if ext is not "" then set slug to text 1 thru -((count ext) + 2) of slug
set postWithDate to (iso_dt & "-" & slug & ".markdown")
if exists postWithDate then
delete postWithDate
end if
set name of copiedPost to postWithDate
end tell
Oh god. Let’s break this down.
The first thing in this file is a utility function for spitting out ISO8601 formatted dates, which I’ll prepend to the filename when I add it to my blog’s repo.
on date_to_iso(dt)
set {year:y, month:m, day:d} to dt
set y to text 2 through -1 of ((y + 10000) as text)
set m to text 2 through -1 of ((m + 100) as text)
set d to text 2 through -1 of ((d + 100) as text)
return y & "-" & m & "-" & d
end date_to_iso
Then we set up a few variables. For some bizarre reason, file system paths in
AppleScript use colons to separate path segments, whatever. We also grab the
current date as dt
and use taht function from before to turn that into a
string.
set destination to "Macintosh HD:Users:rpowell:Projects:rpowelll.github.io:_posts"
set dt to current date
set iso_dt to date_to_iso(dt)
Still with me? Alright now we have to set the source file to the file that’s currently open in iA Writer, that’s pretty easy.
tell application "iA Writer"
set source to file of document 1
end tell
Finally we get to the ugliest, most baffling part of this code. The last part of this script copies our source file to the destination directory, does some atrocious string manipulation to grab the copied file’s name minus the extension1, and finally renames the file by prepending the date, and appending the .markdown file type extension. String manipulation is note AppleScript’s strong suit it turns out, so this code is an unreadable nightmare.
tell application "Finder"
set copiedPost to duplicate file source to folder destination with replacing
set slug to name of copiedPost
set ext to name extension of copiedPost
if ext is not "" then set slug to text 1 thru -((count ext) + 2) of slug
set postWithDate to (iso_dt & "-" & slug & ".markdown")
if exists postWithDate then
delete postWithDate
end if
set name of copiedPost to postWithDate
end tell
Anyway, while AppleScript’s syntax can be frequently frustrating, the promise of ubiquitous, system level scripting and automation is tempting enough for me to endure it. Hopefully I haven’t forgotten all of this next time I need to open up Script Editor.app.
-
I usually just use the .txt extension for Markdown files, because they’re just plain text after all, and iA Writer is set up to use this as the default. However Jekyll needs these files to have a
.md
or.markdown
extension, hence all this noise. ↩