Tasks for today from TaskPaper to Begin

In today’s script, we’re going to swipe through a TaskPaper file, select every task with a due date for today, trim each one from all the tags and send them to Begin so you can kickstart your day. We’re going to unleash the power of the new Launch Center Pro and Pythonista and create an amazing workflow.

First, a few introductions: if you don’t know TaskPaper yet, it is a task manager for plain text files. It has its own syntax and you can sync it with Dropbox. Every plain text aficionado admires TaskPaper for its flexibility.

Begin is a brand-new focused to-do app, which only handles tasks for today and tomorrow. It is gorgeous, truly intuitive and strongly recommended.

Launch Center Pro recently got its 2.0 version, which brought several new features I won’t list here. Eric and Viticci wrote great introductions to the latest release.

You already know Pythonista.

One of the additions of LCP is opening a text file from Dropbox. You can set a path and skip the part when you have to select a file at the Dropbox interface. We’re going to pick one of our TaskPaper files stored in Dropbox and send the content as an argument to Pythonista:

TaskPaper2Begin (the LCP action):


Here we’re telling Pythonista to run a script named TaskPaper2Begin and we’re sending the content of the file Freelance.txt, which is stored within the TaskPaper folder. LCP still doesn’t consider .taskpaper as a valid extension to collect the text. If you use a .taskpaper file instead of a plain text file, you’ll get a short link instead. I hope they’ll soon add the extension to the actionable list so you can get back to your regular files.

Here’s the Pythonista script:

import urllib
import webbrowser
import datetime

taskpaper = sys.argv[1].split('\n')

today = '@due(' + datetime.datetime.now().strftime('%d/%m/%Y') + ')'

broom = {today,'@overdue','\t'}

dueToday = ','.join([last[2:] for last in [' '.join(w for w in due.split() if w.lower() not in broom) for due in [task for task in taskpaper if today in task]]])

begin = 'beginapp://x-callback-url/addTasks?text=' + urllib.quote(dueToday) + '&x-source=Launch%20Center&x-success=launchpro://'


Ok, time for some explanations: taskpaper = sys.argv[1].split(‘\n’) picks the content sent from LCP and creates a list breaking each item on every line break. '@due(' + datetime.datetime.now().strftime(‘%d/%m/%Y’) + ‘)’ creates the tag from TaskPaper which results in @due(12/10/2013), you can make it more US by sorting the date as it pleases you. %d is the current day, %m, current month and %Y is the year in a 4-digit format. You can find more ways to manipulate the date output in the python docs.

The broom variable is a dictionary of terms we want to remove from our tasks, such as the due date tag and the indentation. Python preserves indentation, just as it does with line breaks. Modify this dictionary according to your peculiarities.

dueDate is our big boy and must be explained in parts. [task for task in taskpaper if today in task] creates a list with every line on the major text file that has the due date tag. This is how we select only the tasks due today. ' '.join(w for w in due.split() if w.lower() not in broom) is a loop that trims the words from our broom variable out. It splits every line on white space and looks if the resulting string, in lowercase, matches with one of the items from the dictionary. Then it will put it back together. Often this will leave us with - task. Then, ','.join([last[2:] for last in makes the final loop, which will remove the - from every item and create a comma-separated list afterwards. We convert ['\t\t- iStorage 2 @due(11/10/2013) @overdue', '\t- ComingUp @due(11/10/2013)’] to ’iStorage 2,ComingUp’.

From that moment on, we just encode the outcome and call the Begin url. Easy. But you can do a few more tricks if you have the patience. LCP2 lets you call actions from outside the app, meaning that instead of closing your workflow with x-success=launchpro://, you could pretty well call another action, like reviewing another TaskPaper file. If you tweak this script enough or create a different script in Pythonista for each file, you can generate the biggest chain of events ever seen, with every script calling a different script while sending to Begin every single time.

That’s probably the reason iPhone 5s has a 64-bit chip.

PS: Thanks to Pedro for providing me with his complex TaskPaper files to test this workflow.