This week's sponsor

Vectornator

Graphic Design for the iPad and iPhone – Reimagined!


Compiling and Exporting Chapters for My iOS 12 Review with Drafts 5


Back in June, I wrote on MacStories that I was evaluating whether Drafts 5 could replace Editorial for my Markdown automation and become the app I use to write my annual iOS review. Putting together these longform pieces involves a lot of writing, editing, and navigating between different sections; the more I can automate these tasks, the more time I can spend doing what actually matters for the review – testing the new version of iOS and ensuring the review is up to my standards.

Once I started looking into Drafts 5, I realized I could take advantage of its JavaScript automation engine to build a custom action that would compile the latest version of my iOS review draft and back it up to multiple locations as a single Markdown (.md) text file.

First, some context. I always like to write my iOS reviews in separate text files – one for each chapter – that are eventually compiled into a single "master" file; toward the end of August, I usually start editing this file in Editorial. As I mentioned on MacStories though, this year I wanted to move away from Editorial as I didn't think the app was going to receive major updates anymore; Drafts 5 felt like the safest and most promising bet.

At the same time, I also wanted to simplify my process so that I wouldn't end up writing my review in an app and editing it in another. For the past few years, I've experimented with Scrivener and Ulysses for this, but neither of them is well suited for the unique mix of longform writing and heavy Markdown automation I'm looking for. Drafts 5 felt like the spiritual successor to Editorial that I could fully script and customize to my needs. So for the past three months, I've been writing and editing my upcoming iOS 12 review entirely in Drafts.

Drafts 5 offers native tagging for notes, which can be combined with workspaces and scripting to create dedicated writing environments that can be tied to action groups. My idea was simple enough: given notes that had been tagged with "ios12", I wanted to sort them by title, merge them into a single text file, and save them in iCloud Drive, Dropbox, and Working Copy. With this system, I was able to:

  • Create a separate workspace for the iOS 12 review in Drafts;
  • Name each chapter something along the lines of ## 3. Shortcuts;
  • Sort everything by the order in which chapters would appear on MacStories;
  • Back everything up to three separate locations.

To build this action, I had to turn to JavaScript.

My iOS 12 Review workspace in Drafts 5.

My iOS 12 Review workspace in Drafts 5.

One function of the Draft object in Drafts 5 is the ability to retrieve an array of drafts by querying the app for items that match a specific search string, filter, or tag (or combination of all three). Essentially, this allows you to search Drafts 5 for items that match specific conditions; items can then be iterated upon in JavaScript for additional manipulation. My action involves querying Drafts 5 with a tag filter, which returns an array of drafts that can be read in a repeat loop and appended (one after the other) to a new variable, which then becomes the .md file to share with other apps.

The action is comprised of three steps: a JavaScript one plus two visual actions. Let's take a look at the full script first:

var drafts = Draft.query("", "all", ["ios12", "compile"]);

//Sort matched notes by title

drafts.sort((a,b) => {
return a.content.localeCompare(b.content);
});

//Create empty sections variable and iterate over notes to add them to the variable

var sections = [];

for (var i = 0; i < drafts.length; i++) {
    item = drafts[i];
    if (!item.isArchived){
        sections.push(item.content);
        sections.push("\n\n");
    }
}

var compile = sections.join("");

//Create first backup in Drafts 5 folder in iCloud Drive, runs in the background

var fmCloud = FileManager.createCloud(); // Cloud file in app container
var success = fmCloud.write("/Review.md", compile);

draft.setTemplateTag("file", compile);

Line 1 is where the Draft.query() function searches for all drafts that contain the "ios12" and "compile" tags. If you want to use this action yourself, you'll have to change the tag names between quotes. Also, as detailed in the app's documentation, you can optionally query the app for drafts that contain a specific string of text; for the purpose of this action, I just need to find all drafts that have been assigned two specific tags.

Once the action has an array of drafts, it can sort them by name (I have to thank Greg Pierce for the suggestion here) and append each one to an empty array created on Line 11. On Line 21, all the items in the new array are then joined in a single compile variable that is assigned the [[file]] template tag at the end of the script. This tag allows us to reference the newly generated file in other non-script steps of the same action, and it's one of my favorite features of Drafts 5's JavaScript as it provides a native bridge between scripting and built-in actions.

If you look at the script closely, you'll see that one of the first copies of the master file is saved from the script itself. On Lines 25-26, Drafts uses the FileManager object to turn the compile variable into a file named Review.md (again, you should change this) that is automatically saved in iCloud Drive/Drafts 5. While I would have preferred being able to save in any iCloud Drive folder via JavaScript (apps still can't programmatically write files outside of their container without manual user input), I still end up with a plain text copy of the file backed up in iCloud Drive with just two lines of code, which is remarkable.

Saving a compiled draft of the review in Dropbox.

Saving a compiled draft of the review in Dropbox.

The last two steps are native actions that use the [[file]] tag to save a compiled copy of the review in Dropbox and Working Copy, respectively. Dropbox is a built-in action that accepts a file name and path (which you should also change) and which can be set to overwrite an existing file of the same name. I choose to replace files because I have my editing history in Drafts and Working Copy anyway; plus, I don't want to end up with dozens of similarly named files in Dropbox.

Finally, because iOS doesn't have a way to save data directly into another app's container, saving the .md file to a GitHub repository in Working Copy is done via the share sheet. Just like other actions, we can use the [[file]] tag as input for the share sheet, which will then pass the file to the Working Copy extension. As in previous years, I relied on GitHub to keep track of changes to the review throughout the summer and share revisions of the draft with my editor and my colleagues at MacStories.

Even though Drafts still isn't nearly as intuitive or visual as Editorial or Shortcuts when it comes to automation (it still relies too much on JavaScript in my opinion; there should be more native actions that perform the same functionalities), I love the fact that I can fully customize my text editor and build actions based on tagging. Drafts 5 is the only app on iOS that can scale from being a minimalistic note-taking scratchpad to a viable BBEdit alternative powered by actions and scripts.

The more I look into Drafts 5, the more I see untapped potential for serious Markdown automation; I'm excited to continue my experiments for MacStories and the Club over the next few months.

You can download the action here.

Unlock MacStories Extras

Club MacStories offers exclusive access to extra MacStories content, delivered every week; it's also a way to support us directly.

Club MacStories will help you discover the best apps for your devices and get the most out of your iPhone, iPad, and Mac. Plus, it's made in Italy.

Starting at $5/month, with an annual option available. Join the Club.

A Club MacStories membership includes:

  • MacStories Weekly newsletter, delivered every week on Friday with app collections, tips, iOS workflows, and more;
  • Monthly Log newsletter, delivered once every month with behind-the-scenes stories, app notes, personal journals, and more;
  • Access to occasional giveaways, discounts, and free downloads.