I just said what I said and it was wrong
Or was taken wrong

I’ve been writing more on my iPad recently; not just blog posts, but reports for work, too. Because I have a lot of helper scripts and macros built up over many years of working on a Mac, writing on the iPad is still slower. But I’m gradually building up a set of iOS tools and techniques to make the process go faster. Today’s post is about a Workflow I built yesterday with advice from iOS automation experts conveyed over Twitter.

For several years, I wrote reports for work using a Markdown→LaTeX→PDF workflow. For most of those years, it was rare for me to have to edit the LaTeX before turning it into a PDF. Recently, though, that rarity has disappeared, mainly because my reports have more tables and figures of varying size that need to be carefully positioned, something that can’t be done in Markdown. A few months ago I decided it would be more efficient to just write in LaTeX from the start. This wasn’t as big a change as you might think. I used to write in LaTeX directly, and the combination of TextExpander and a few old scripts I resurrected got me back up to speed relatively quickly—on the Mac, anyway.

On iOS, most of the TextExpander snippets I built for writing in LaTeX work fine, but the helper scripts, which tend to rely on AppleScript, don’t. One of the scripts I definitely wanted an iOS counterpart for was one that extracted the contact information from a client in a particular format. In my reports, the title page usually includes section for the name, company, and address of the client. This is added in the LaTeX source code by this:

where \client is a LaTeX command I created long ago, and its argument needs the usual LaTeX double backslashes to designate line breaks. Also, ampersands, which are special characters in LaTeX, need to be escaped.

I thought I could whip something up in Workflow, but my limited understanding of Workflow isn’t conducive to whipping. When I first tried to put something together a couple of weeks ago, it looked to me as if I was going to have to painstakingly extract every piece of information from the selected contact, create variables to store them in, and then put those variables together into a new string of text. So I gave up.

Yesterday I decided to ask for help.

I would like to extract from a selected contact a standard name/address block as plain text:

As you can see, I asked for something a bit simpler than what I really wanted, and I was kind of expecting suggestions for an app that would do the trick. But I soon got a response from Ari Weinstein with a Workflow solution:

Since Ari is a co-developer of Workflow, I kind of figured he knew what he was talking about. But I didn’t, and it’s because I didn’t appreciate Workflow’s magic variables. I’ve always thought of Workflow as being almost like a functional language, where each action transforms the data passed to in and sends it along to the next action in turn. That, at least, is what I thought happened when the actions are connected by lines.

Which is why I didn’t understand Ari’s workflow at first. I figured that if it was extracting the Street Address in the second step, there’d be no way for it to get ahold of the Name and Company in the fourth step. What I didn’t appreciate was that there can be side effects the usual view of a workflow doesn’t show you. In this case, the Contact that’s selected in the first step is saved to a magic variable (called “Contact”) that remains available for use in later steps. So the third and fourth steps have access to all the Contact information even after the extraction of the Street Address in the second step.

Ari’s sample is a standard workflow that would have to be run from within Workflow itself or from a launcher app like Launch Center Pro. I was thinking about how to turn it into an Action Extension that could be called from within Contacts when I noticed I had a Twitter reply from Federico Viticci:

His suggestion is set up as an Action Extension that accepts only Contacts and extracts the info from the Workflow Input magic variable. Just what I was going to do.

“My” final workflow, called LaTeX Address, combines what I learned from Ari and Federico and adds some search-and-replace stuff to handle the LaTeX-specific parts:

The first two steps create a text variable named Ret that consists of a single line break. We’ll see why I needed it in a bit.

Steps 3–5 are the Ari/Federico mashup. I couldn’t use Federico’s suggestion to just add Workflow input:Street Address to the end of the block because my contacts usually include the country, even though the country is almost always the US, and I didn’t want that at the end of the block. At some point, I’ll improve this by writing up a filter that deletes the country line only if it’s the US, but this will do until I get another job with a non-US client.

Step 6 escapes the ampersands, and Step 7 adds the double backslashes to the ends of each line. You need four backslashes to get two in the output because regexes need two to produce one. I thought I could use \n at the end of the replacement string to get a line break, but I couldn’t get that to work. Thus, the Ret variable defined at the beginning of the workflow.

Finally, Step 8 puts the text on the clipboard, ready for pasting into a LaTeX document.

My plan is to use this extension in Split View, with my text editor, currently Textastic, on one side and Contacts on the other. When I need to insert the client info, I find it in Contacts, tap Share Contact to bring up the Sharing Sheet, and select the Run Workflow action.

This brings up the list of Workflow Action Extensions that can accept Contacts. I choose LaTeX Address from the list, switch focus back to Textastic, and paste the text block where it belongs. Boom.

I’ll try to remember to look for magic variables the next time I make a workflow. There is a trick to making them visible. When you’re editing a workflow and can insert a variable (magic or otherwise), a button with a magic wand will appear in the special keyboard row.

Tapping it will give you a new view of your workflow, with the magic variables appearing where the workflow creates them.

You don’t need to do this, as all of these variables should appear in the special keyboard row if you keep scrolling it to the right. But I find it easier to understand what they are and where they come from in this view.

Thanks to everyone who had suggestions for me, especially Ari and Federico.