{"id":576,"date":"2009-06-01T08:19:02","date_gmt":"2009-06-01T13:19:02","guid":{"rendered":"http:\/\/poojanwagh.opalstacked.com\/poojanblog\/2009\/06\/gtd-with-python-git-vim-and-asciidoc\/"},"modified":"2009-06-01T08:19:02","modified_gmt":"2009-06-01T13:19:02","slug":"gtd-with-python-git-vim-and-asciidoc","status":"publish","type":"post","link":"https:\/\/poojanblog.com\/blog\/2009\/06\/gtd-with-python-git-vim-and-asciidoc\/","title":{"rendered":"GTD with Python, git, vim, and asciidoc"},"content":{"rendered":"<p>I r<a href=\"http:\/\/poojanblog.com\/poojanblog\/2009\/05\/my-gtd-setup\/\" target=\"_blank\">ecently detailed<\/a> the high-level setup of my latest GTD roll out. This follow-up post has a high <a title=\"&quot;geek factor&quot; is a term used at lifehacker\" href=\"http:\/\/lifehacker.com\/software\/geek-to-live\/\" target=\"_blank\">&ldquo;geek factor&rdquo;<\/a> and contains the details of how I do this using computer automation (Python scripts).<\/p>\n<p> <!--more-->  <\/p>\n<p>When I process my inboxes, I write one line per task in one of two text files (gtd-work.txt, gtd-personal.txt&mdash;heretofore referred to as gtd-x). The format is:<\/p>\n<blockquote>\n<p>[<em>project<\/em>] | <em>task<\/em><font face=\"Courier\"> | <\/font>@<em>context<\/em><\/p>\n<\/blockquote>\n<p>This format handles both individual tasks (not attached to a &ldquo;project&rdquo;) 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.<\/p>\n<blockquote>\n<p>Blog about python GTD setup | Find 1st version of python script &amp; save on desktop | @HomeComputer      <br \/>Do laundry | @Home<\/p>\n<\/blockquote>\n<p>The context file would contain:<\/p>\n<blockquote>\n<p>@HomeComputer      <br \/>Blog about python GTD setup | Find 1st version of python script &amp; save on desktop | @HomeComputer<\/p>\n<p>@Home      <br \/>Do laundry | @Home       <\/p>\n<\/blockquote>\n<p>You&rsquo;ll notice that the context (@Home for example) is redundant. I didn&rsquo;t care too much: the script organizes things the way I want it (by context) and gets things done.<\/p>\n<p>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.<\/p>\n<p>Here&rsquo;s the Python script:<\/p>\n<blockquote>\n<pre>import re\nimport hashlib\n\ngtdfiles = [&quot;gtd-personal.txt&quot;, &quot;gtd-work.txt&quot;]\n\ndef writeTags(dictTags, fout):\n   keys = list(dictTags.keys())\n   keys.sort()\n   for k in keys:\n      print(k + &quot;\\t&quot; + dictTags[k]['file'] + &quot;\\t&quot; + str(dictTags[k]['line']), file=fout)\n\ndef formatCtxLine(actionLine, lineHash):\n   return line.strip() + &quot;\\n\/\/ &quot; + lineHash\n\nreContext = re.compile(r'@\\w+')\ndictContext = {}\ndictTags = {}\n\n\nfor gtdf in gtdfiles:\n   fin = open(gtdf, 'r')\n\n   lineno = 0\n   for line in fin:\n      lineno += 1\n      print(line)\n      lContexts = reContext.findall(line)\n      for sCtx in lContexts:                  \n         lineHash = hashlib.md5(line.encode()).hexdigest()\n         dictTags[lineHash] = dict(file=gtdf, line=lineno)\n         if sCtx in dictContext:            \n            dictContext[sCtx].append(formatCtxLine(line, lineHash))\n         else:\n            dictContext[sCtx] = [formatCtxLine(line, lineHash)]\n            \n   fin.close()\n\nftags = open(&quot;tags&quot;, 'w')\nwriteTags(dictTags, ftags)\nftags.close()\n\nfout = open(&quot;context.txt&quot;, 'w')\n\nfor k,v in dictContext.items():\n   print(&quot;&quot;, file=fout)\n   #print(&quot;&lt;&lt;&lt;&quot;, file=fout)\n   print(&quot;&quot;, file=fout)\n   print('*' + k + '*', file=fout)\n   print('', file=fout)\n\n   for na in v:\n      print('-  ' + na, file=fout)\n\nprint(&quot;&quot;, file=fout)\nprint(&quot;&quot;, file=fout)\nprint(&quot;\/\/    vim:set readonly&quot;, file=fout)\nfout.close()<\/pre>\n<\/blockquote>\n<p>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&mdash;except I&rsquo;ve declared an indefinite moratorium on changing things.)<\/p>\n<p>I also keep one <a title=\"Matthew Cornell: Big Arse Text File\" href=\"http:\/\/www.matthewcornell.org\/blog\/2005\/08\/my-big-arse-text-file-poor-mans.html\" target=\"_blank\">big<\/a> <a title=\"43 Folders: big text file\" href=\"http:\/\/www.43folders.com\/2005\/08\/17\/life-inside-one-big-text-file\" target=\"_blank\">text<\/a> <a title=\"Giles Turnbull: the original one-big-text file\" href=\"http:\/\/www.oreillynet.com\/mac\/blog\/2005\/08\/living_in_text_files.html\" target=\"_blank\">file<\/a> that logs what I&rsquo;m up to (when I feel like logging what I&rsquo;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.<\/p>\n<p>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: <code>\\gt<\/code> runs the python script above and <code>\\go<\/code> runs ASCIIDOC to generate the HTML, so I don&rsquo;t need to leave the editor to see updates to what I&rsquo;m doing.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I recently detailed the high-level setup of my latest GTD roll out. This follow-up post has a high &ldquo;geek factor&rdquo; and contains the details of how I do this using computer automation (Python scripts).<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[4,53],"tags":[156,31,33,98,150,155],"class_list":["post-576","post","type-post","status-publish","format-standard","hentry","category-desktop-computing","category-productivity","tag-asciidoc","tag-git","tag-gtd","tag-mercurial","tag-python","tag-vim"],"jetpack_featured_media_url":"","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/poojanblog.com\/blog\/wp-json\/wp\/v2\/posts\/576","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/poojanblog.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/poojanblog.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/poojanblog.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/poojanblog.com\/blog\/wp-json\/wp\/v2\/comments?post=576"}],"version-history":[{"count":0,"href":"https:\/\/poojanblog.com\/blog\/wp-json\/wp\/v2\/posts\/576\/revisions"}],"wp:attachment":[{"href":"https:\/\/poojanblog.com\/blog\/wp-json\/wp\/v2\/media?parent=576"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/poojanblog.com\/blog\/wp-json\/wp\/v2\/categories?post=576"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/poojanblog.com\/blog\/wp-json\/wp\/v2\/tags?post=576"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}