WikidPad and Getting Things Done
Getting Things Done is a personal information management system described by David Allen in his books "Getting Things Done: The Art of Stress-Free Productivity" and "Ready for Anything: 52 Productivity Principles for Work and Life". Some of the main points are to remain flexible and to keep things simple. In these two issues WikidPad can help you.
- Flexibility with WikiWord automatic linking
- Simplicity with free-format text entry
Beware, not compatible with 1.6beta
Just so that no-one else wastes an hour or two trying to get these scripts working with 1.6beta - work is needed especially with the interface to the editor to make it work properly with 1.6beta.
Next Actions by Erik Neumann
- Create user_extensions directory under your WikidPad directory
- Copy there "WikidPadHooks?.py" and "WikiSyntax?.py" from extensions directory
- Never edit original files in extensions, only copies in user_extensions directory
- Create NextActions and WaitingFor pages in your wiki
- Edit WikiSyntax?.py file: add wait into ToDoRE, ToDoREWithContent and ToDoREWithCapturing lists
- Edit WikidPadHooks?.py file: add following script into openedWikiWord function
- CLOSE AND RESTART WikidPad to activate the changes
def openedWikiWord(wikidPad, wikiWord): if wikiWord == "NextActions": # editor = wikidPad.editor editor = wikidPad.getActiveEditor() todos = wikidPad.wikiData.getTodos() todos.sort() #FindText returns start position or -1 if not found s = editor.FindText(0, editor.GetLength(), "+++Actions from projects:", 0) s = editor.PositionFromLine(1+editor.LineFromPosition(s)) editor.SetSelection(s, editor.GetLength()) editor.ReplaceSelection("\n") for todo in todos: if str(todo[1])[:4] == "todo": # filter out others (like done:) should not include 5th char = ':' editor.AddText(str(todo[0])) editor.AddText(" ") editor.AddText(str(todo[1])[5:]) editor.AddText("\n") elif wikiWord == "WaitingFor": # editor = wikidPad.editor editor = wikidPad.getActiveEditor() todos = wikidPad.wikiData.getTodos() todos.sort() #FindText returns start position or -1 if not found s = editor.FindText(0, editor.GetLength(), "+++Collected from projects:", 0) s = editor.PositionFromLine(1+editor.LineFromPosition(s)) editor.SetSelection(s, editor.GetLength()) editor.ReplaceSelection("\n") for todo in todos: if str(todo[1])[:4] == "wait": # filter out others (like done:) should not include 5th char = ':' editor.AddText(str(todo[0])) editor.AddText(" ") editor.AddText(str(todo[1])[5:]) editor.AddText("\n") pass
Possible Problems
Make sure your python code indentation is correct
Next Actions (Take Two) -- <icosahedral at gmail dot com>
Thanks Eric! I've edited the above function to organize by context instead of by project name. If you were to enter an entry as "todo.work", it will now show up under a header entry of "@work". Forgive the code, I'm new to python. (Although -- now that I've played with it -- I do see the appeal!)
def openedWikiWord(wikidPad, wikiWord): def customCompare(todo1, todo2): return cmp(todo1[1], todo2[1]) if wikiWord == "NextActions": # editor = wikidPad.editor editor = wikidPad.getActiveEditor() todos = wikidPad.wikiData.getTodos() todos.sort(customCompare) #FindText returns start position or -1 if not found s = editor.FindText(0, editor.GetLength(), "+++Actions from projects:", 0) s = editor.PositionFromLine(1+editor.LineFromPosition(s)) editor.SetSelection(s, editor.GetLength()) editor.ReplaceSelection("\n") pt = re.compile('todo\.(.+?):') context1t = "." for todo in todos: context2t = context1t mt = pt.search(str(todo[1])) if mt != None: context1t = mt.group(1) if (context1t != context2t): editor.AddText("\n++ @") editor.AddText(context1t) editor.AddText("\n") if str(todo[1])[:4] == "todo": # filter out others (like done:) should not include 5th char = ':' editor.AddText(str(todo[0])) editor.AddText(" ") editor.AddText(str(todo[1])[5:]) editor.AddText("\n") elif wikiWord == "WaitingFor": # editor = wikidPad.editor editor = wikidPad.getActiveEditor() todos = wikidPad.wikiData.getTodos() todos.sort(customCompare) #FindText returns start position or -1 if not found s = editor.FindText(0, editor.GetLength(), "+++Collected from projects:", 0) s = editor.PositionFromLine(1+editor.LineFromPosition(s)) editor.SetSelection(s, editor.GetLength()) editor.ReplaceSelection("\n") pw = re.compile('wait\.(.+?):') context1w = "." for todo in todos: context2w = context1w mw = pw.search(str(todo[1])) if mw != None: context1w = mw.group(1) if (context1w != context2w): editor.AddText("\n++ @") editor.AddText(context1w) editor.AddText("\n") if str(todo[1])[:4] == "wait": # filter out others (like done:) should not include 5th char = ':' editor.AddText(str(todo[0])) editor.AddText(" ") editor.AddText(str(todo[1])[5:]) editor.AddText("\n") pass
Is there a non programmer solution ?
I just do not know where to put "wait" in the python file exactly. Wikipad is giving a syntax error.
The location for the added "wait"
I'm new to WikidPad and Python too, but I think it should be added like here:
ToDoREWithContent = re.compile ....
... (?:todo|done|wait|action|track|issue|question|project|wait)(?:\.[^:\s]+)?)"
A small fix: No need to add 'wait' twice (Reinhard Engel):
ToDoREWithContent = re.compile ....
... (?:todo|done|wait|action|track|issue|question|project)(?:\.[^:\s]+)?)"
One more fix
I had to add
import pwiki.srePersistent as re
in the begining of WikidPadHooks?.py
Mods from Mike Crowe
Email me at mike at mikeandkellycrowe dot com
I based mine to get categories on SortedTodos. Breaks up by tags, which is what I wanted. Notes:
- For dumb people like me, make sure you put it in openedWikiWord and not openWikiWord. Big Difference ;)
- This is compatible with 1.7a.
- In your main page, enter a link of ![Todo] to activate
Code:
def openedWikiWord(wikidPad, wikiWord): """ Called when a new or existing wiki word was opened successfully. wikiWord -- name of the wiki word to create """ if (wikiWord[:4].upper() == "TODO"): # tags contains the (Tag, TagHeader) pairs - customize the list of sort categories here: # TagHeaders are the descriptive headings that will be shown for each category. tags = [('High','Tagged HIGH !'), ('_spec.SPACER',''), ('Next','Next Actions'), ('ThisWeek','Tagged for This Week'), ('_spec.SPACER',''), ('SomeDay','SomeDay / Maybe'), ('_spec.SPACER',''), ('TimeToTime','Tagged for from time to time'), ('_spec.SPACER',''), ('Low','Tagged as LOW'), ('_spec.SPACER',''), ('VeryLow','Tagged as Very LOW')] # MikeCrowe -- Untagged always at end of list tagEnd = [ ('_spec.SPACER',''), ('_spec.NOTAGS','Untagged Todos')] srchstr = wikiWord[4:] # get all todos with 'todo' in them to seperate list to be used here: todosFull = wikidPad.wikiData.getTodos() todos = [todo for todo in todosFull if ('todo' in todo[1]) ] # and srchstr in todo[1]) ] #clean the page code - and insert the harvested todos after placemark = '++ auto-harvested todos:' editor = wikidPad.getActiveEditor() st = editor.FindText(0, editor.GetLength(), "++ auto-harvested todos:", 0) st = editor.PositionFromLine(1+editor.LineFromPosition(st)) editor.SetSelection(st, editor.GetLength()) editor.ReplaceSelection("\n") # handle the page by displaying all keywords with srchstr -> list all todos : tagAdded = True #used to stop two spacers in a row checkTags = [tag[0] for tag in tags] # MikeCrowe -- code to search for tags not in above list and automatically add for todo in todos: allTodo = todo[1].split(":") words = allTodo[0].split(".") for word in words[1:]: if not word in checkTags: tags.append( ("_spec.SPACER","") ) tags.append( (word,"Tagged "+word) ) checkTags.append(word) tags = tags + tagEnd for tag in tags: wroteHeader = False #used to make sure that header is written only once - in a non-empty category # handle special tag '_spec.SPACER' by writing SPACERs in the tag list: if tag[0] == '_spec.SPACER' and tagAdded: editor.AddText('\n' + ('-'*70) + '\n') tagAdded = False # handle special NOTAG in the tag list # This displays all untagged todos : elif tag[0] != '_spec.NOTAGS': for todo in todos: if (tag[0] in todo[1]): if not wroteHeader: editor.AddText('\n++ ' + tag[1] + ' :\n') wroteHeader = True s = str(todo[1]) editor.AddText(' * '+ str(todo[0]) + ': '+ s[s.find(':')+1:] + '\n') todos[todos.index(todo)] = ('DEL','DEL') #marks that todo to be ignored tagAdded = True # handle normal Tags - write the todos for that tag: else: for todo in todos: foundTag = False for t in tags: if t[0] in todo[1]: foundTag = True break if not foundTag and todo[0] != 'DEL': if not wroteHeader: editor.AddText('\n++ ' + tag[1] + ' :\n') wroteHeader = True s = str(todo[1]) editor.AddText(' * '+ str(todo[0]) + ': '+ s[s.find(':')+1:] + '\n') todos[todos.index(todo)] = ('DEL','DEL') #marks that todo to be ignored tagAdded = True
Adding Default Icon
I learned quickly using the above script, that since the page is dynamically created every time you open it, any icon assigned to distinguish it disappears.
I added the following line to the end of the above script:
editor.AddText('[icon: eye]')
This adds my preferred icon back into the tree view to assist me in distinguishing it. (It's simple, but it took me longer than it should have to figure out where to locate it, not knowing Python.)
Fix for Mike's Code
As far as I see the following snippet of the code above:
if not foundTag and todo[0] != 'DEL':
if not wroteHeader:
editor.AddText('\n++ ' + tag[1] + ' :\n')
wroteHeader = True
s = str(todo[1])
editor.AddText(' * '+ str(todo[0]) + ': '+ s[s.find(':')+1:] + '\n')
todos[todos.index(todo)] = ('DEL','DEL') #marks that todo to be ignored
tagAdded = True
should read like this (fixed indention for 2 lines):
if not foundTag and todo[0] != 'DEL':
if not wroteHeader:
editor.AddText('\n++ ' + tag[1] + ' :\n')
wroteHeader = True
s = str(todo[1])
editor.AddText(' * '+ str(todo[0]) + ': '+ s[s.find(':')+1:] + '\n')
todos[todos.index(todo)] = ('DEL','DEL') #marks that todo to be ignored
tagAdded = True
to list all untagged todos and not only the first one.
Another idea for Mike's code
Add color to different tags. for example if you define:
tags = [
('Tickler','Things to Remember','#0000ff'),
('_spec.SPACER',''),
('Active','Active - On Work Now','#ff00ff'),
('_spec.SPACER',''),
('Next','Next Actions','#ff0000'),
('_spec.SPACER',''),
('Highest','HIGHEST Priority!!!','#cc0000'),
('_spec.SPACER','',''),
('High','HIGH Priority!','#800000'),
('_spec.SPACER','',''),
('ThisWeek','Tasks for This Week','#808000'),
('_spec.SPACER','',''),
('Later','To be done Later','#008080'),
('_spec.SPACER','',''),
('TimeToTime','To be Done from time to time',''),
('_spec.SPACER','',''),
('Low','LOW Priority',''),
('_spec.SPACER','',''),
('VeryLow','Lowest Priority',''),
('_spec.SPACER','',''),
('SomeDay','SomeDay / Maybe','')
]
you can change Mike's code as follows:
elif tag[0] != '_spec.NOTAGS':
addedColor=0
for todo in todos:
if (tag[0] in todo[1]):
if not wroteHeader:
if (len(tag)>2 and tag[2] != ''):
addedColor=1
editor.AddText("\n<font color="+tag[2]+">\n")
editor.AddText('\n++ ' + tag[1] + ' :\n')
wroteHeader = True
s = str(todo[1])
s1=s[:s.find(':')]
s1=re.sub(r'(todo|Active|Highest|High|Next|ThisWeek|Later|SomeDay|TimeToTime|Low|VeryLow|Tickler).','',s1)
editor.AddText(' * '+ s1+ ' -> [' +str(todo[0]) + ']: ' + s[s.find(':')+1:] + '\n')
todos[todos.index(todo)] = ('DEL','DEL') #marks that todo to be ignored
tagAdded = True
if (addedColor):
editor.AddText("\n</font>\n")
addedColor=0
and you'll get your different priorities colored...
would somebody put up everything here into downloadable files for dummies to easily download the files instead wrong editing that cause more troubles. tia.
Be efficient with wikipad
I wrote 2 articles to this day about GTD and the use of wikipad : The main page of the blog | Article on wikipad | Article about the GTD inbox
Attachments
- WikidPadHooks.py (12 kB) - An Example of how I use GTD... (+ListProp? + DoneTasks?...), added by Avi on Sun Jun 24 09:53:55 2007.
