Poojan (Wagh) Blog

Requests for comment

GTD with Python, git, vim, and asciidoc

with 2 comments

I recently detailed the high-level setup of my latest GTD roll out. This follow-up post has a high “geek factor” and contains the details of how I do this using computer automation (Python scripts).

When I process my inboxes, I write one line per task in one of two text files (gtd-work.txt, gtd-personal.txt—heretofore referred to as gtd-x). The format is:

[project] | task | @context

This format handles both individual tasks (not attached to a “project”) and multi-step projects. I wrote a small python script that parses these files and spits out one file called context.txt that has these tasks sorted by context.

Blog about python GTD setup | Find 1st version of python script & save on desktop | @HomeComputer
Do laundry | @Home

The context file would contain:

Blog about python GTD setup | Find 1st version of python script & save on desktop | @HomeComputer

Do laundry | @Home

You’ll notice that the context (@Home for example) is redundant. I didn’t care too much: the script organizes things the way I want it (by context) and gets things done.

Since I use the text editor vim, the python script also creates a tags file that links entries in the context.txt file back to my two gtd-x files.

Here’s the Python script:

import re
import hashlib

gtdfiles = ["gtd-personal.txt", "gtd-work.txt"]

def writeTags(dictTags, fout):
   keys = list(dictTags.keys())
   for k in keys:
      print(k + "\t" + dictTags[k]['file'] + "\t" + str(dictTags[k]['line']), file=fout)

def formatCtxLine(actionLine, lineHash):
   return line.strip() + "\n// " + lineHash

reContext = re.compile(r'@\w+')
dictContext = {}
dictTags = {}

for gtdf in gtdfiles:
   fin = open(gtdf, 'r')

   lineno = 0
   for line in fin:
      lineno += 1
      lContexts = reContext.findall(line)
      for sCtx in lContexts:                  
         lineHash = hashlib.md5(line.encode()).hexdigest()
         dictTags[lineHash] = dict(file=gtdf, line=lineno)
         if sCtx in dictContext:            
            dictContext[sCtx].append(formatCtxLine(line, lineHash))
            dictContext[sCtx] = [formatCtxLine(line, lineHash)]

ftags = open("tags", 'w')
writeTags(dictTags, ftags)

fout = open("context.txt", 'w')

for k,v in dictContext.items():
   print("", file=fout)
   #print("<<<", file=fout)
   print("", file=fout)
   print('*' + k + '*', file=fout)
   print('', file=fout)

   for na in v:
      print('-  ' + na, file=fout)

print("", file=fout)
print("", file=fout)
print("//    vim:set readonly", file=fout)

I sync the gtd-x, context, tags, and python files using git. (I started with Mercurial (Hg), switched to git, and recently am thinking of switching back due to better Windows support from Hg—except I’ve declared an indefinite moratorium on changing things.)

I also keep one big text file that logs what I’m up to (when I feel like logging what I’m up to). I have the python script search that file, too, so I can embed a to-do in the file wherever I want.

All files are in asciidoc format, so I can generate good-looking HTML without sacrificing the speed of editing with VIM. I have two key macros mapped in vim: \gt runs the python script above and \go runs ASCIIDOC to generate the HTML, so I don’t need to leave the editor to see updates to what I’m doing.

Written by PoojanWagh

June 1st, 2009 at 8:19 am

2 Responses to 'GTD with Python, git, vim, and asciidoc'

Subscribe to comments with RSS or TrackBack to 'GTD with Python, git, vim, and asciidoc'.

  1. Have you thought about adding a priority to the task within each context e.g. should I do the laundry or dishes first @Home


    19 May 14 at 10:46 am

  2. Hi, John.

    The original GTD process discourages the use of priority. Basically, priority should be dynamic, and recording it statically in your to-do list is discouraged. The question of “what to do next” is too dynamic to capture statically.

    Dave Allen recommends, instead that when faced with “what to do next”, you scan your list and decide at the moment.

    And for me, if I do laundry or dishes at home, either one would be a big win, regardless of order. Ha!


    11 Jul 14 at 11:37 am

Leave a Reply