Wednesday, February 13, 2013

Linking Drafts, Day One, and TextExpander with Fill-in Expansion on iOS

Inspired by Federico Viticci (@viticci) of MacStories who has begun automating the bejeezus out of his iPad with Pythonista, I started looking at doing the same to reduce my dependency on needing my MacBook Pro around at all times.

As part of my automation, I set up a number of TextExpander 4 snippets to help me create recurring entries in my Day One journal. These snippets use a feature in TextExpander 4 that allows you to create fill-ins, or, essentially fill-in form elements you can use to replace pieces of your template.

When I tried to move this workflow to iOS I found out, to my chagrin, that TextExpander touch doesn’t support fill-ins (checking with @TextExpander on Twitter confirmed this, but I was unable to determine if it’s a shortcoming of iOS, the TextExpander touch SDK, or a limitation imposed by Apple). After racking my brain, I finally decided to buckle down and write the glue the process needed. After all, it’s just text parsing, right? I’m vaguely familiar with Python, though I’m an old school Perl guy–how hard can it be?

To make a long story short, I made it through. The script’s not my prettiest work, but it’s so far, definitely functional. You can grab the script here if you want to take a look at it. [Edit: Since releasing it, I’ve made a few changes to my own copy of the script. I’ve outlined those below.]

Gist


You can also download the code in a GitHub gist here. This should make it a bit easier to import into Pythonista using the gist download trick.

TextExpander/TextExpander touch


In order for this to work you need both TextExpander for Mac and TextExpander touch (for iOS). You’ll need to set up the snippets with fill-ins you want on the Mac and sync them to iOS. (Though, I suppose you could roll them yourself if you were masochistic.)

Once you have your snippets set up to your liking, you can set up the workflow.

Drafts


Drafts is the key to making this work. The latest major release introduced custom URL actions which are used to trigger the whole workflow. Drafts also includes the TextExpander touch SDK allowing it to take advantage of TextExpander snippet expansion (make sure snippet sharing it enabled in the settings). If you enter your shortcut text in a draft, it will immediately expand. If your snippet has fill-ins in it, you’ll see them unexpanded in your text enclosed in %’s.

To create the workflow, open Drafts’ settings and create a custom URL action as follows:
pythonista://Expander?action=run&argv=[[draft]]
This will send the current contents of your draft to Pythonista and run the Expander script stored within (you may need to tweak this if you’ve named the script something different). I saved my custom action as “Expand Fill-ins.” Once the rest of the steps are configured, you’re ready to go. All you need to do is expand your snippet in Drafts, select the Expand Fill-ins custom action, and your completed, filled-in, snippet will be posted to a new entry in Day One. The python script, when complete, posts a URL back to Drafts with the modified snippet and calls Drafts’ built-in Send to Day One action to complete the work.

Pythonista


If Drafts is the key to making this work then Pythonista is the lock. For the most part, the script takes care of all the havy lifting, but you will need to bring the script into Pythonista yourself (limitation of Apple’s App Store rules). The Pythonista site has some more details on this, but, personally, I opened the script in an editor (in my case, Textastic), copied out the text, and pasted it into a new script inside Pythonista.

When the script runs, it parses the TextExpander fill-in syntax and creates prompts for each on the Pythonista console where you can fill in the values. When you’ve completed the last one, the workflow continues as outlined above.

Limitations


Currently, the expander script does not support the “optional section” fill-in type. It does support the other three (single-line, multi-line, and popup menu). The script is also entirely console-based and, while it does some basic validation checking, it doesn’t provide a GUI or the ability to edit your fill-ins before committing them. (The code is available under a non-restrictive Creative Commons license, so an enterprising soul could take this to the next level.)

Day One


Day One is the final step in this process. All that’s needed is you have it installed and the Send to Day One action be enabled in Drafts.

Update


In my personal copy of the script, I’ve cleaned up the rogue semicolons (python doesn’t seem to care, but I do most of my work in Objective-C, JavaScript, Perl, and other C-based languages so it’s a habit) and added the following line right under ### MAIN ###:
console.clear()
You will also need to import console at the top of the script. This does nothing more than clear the Pythonista console before it starts prompting. I find that this makes for a cleaner and less-confusing experience.

Update 2


Smile has added fill-in support to the TextExpander touch SDK as of version 2.0. The change requires some additional work by each developer to implement it, so it may be some time before your favorite app has it available.