Notebook App - Todo Code

This is User Code to make a simple todo system in your notebooks of the great Notebook App. It allows you to have 1 page of active todo's broken into categories. You then mark items done by wrapping them in <x>...</x>. When you want, you can call the function (I do it via a UserMenu), "TodoArchiveCompleted". This will move all completed items off your "Active" page onto an archived page. The archived page is by day. If you name your main Todo page "Todo", the archived page will be "Todo - 2010-02-16" for example. It will move the completed items and append onto the end the category as in "(Category Name)".

To use, create a new page to store your "active" todo's. I named mine "Todo". You can then create entries such as:

 = Home =
 * A: Replace tile in kitchen

 = Yard =
 * B: Plant shrubs around the house

The "A" or "B" in my example is the priority. You can use what you want here, but when viewing the prioritized page, it uses lsort on the task items, so keep that in mind. Priorities are easy, for instance, 1, 2, 3. You can use the A1, A2, A3, B1, ... system for A=high, B=medium, C=low, 1 = High Effort, 2 = Medium Effort, 3 = Low Effort, or what I do (simple) A = Have to do, want to do, B = Have to do, don't want to do, C = Don't have to do, want to do, D = Don't have to do, don't want to do.

When you complete something, just wrap it in <x>...</x>. For example:

 * <x>B: Plant shrubs around the house</x>

When you have too many completed items in your todo list (it's nice to see some as it shows progress!), you can call the function "TodoArchiveCompleted". This will move them to the archived page.

You can further create a page for showing you all your active todo's sorted by project then priority. To do this, create a page and place the page macro "TodoByPriority" as it's sole content. This page should be named "BasePage - By Priority". The macro will take the "BasePage" part and query the active items from it.

On with the code:

 #Tcl
 #
 # Simple Todo System
 #

 proc TodoByPriority {} {
     regexp -nocase {^(.*) - .*$} [current] totalMatch basePage
     set content [pageget $basePage]
     set newContent ""
     set items {}

     foreach line [split $content \n] {
         if {[regexp -nocase {^=+ .* =+$} $line]} {
             foreach item [lsort $items] {
                 append newContent ${item}\n
             }
             if {[llength $items] > 0} {
                 append newContent \n
             }
             append newContent $line
             set items {}
         } else {
             lappend items $line
         }
     }

     foreach item [lsort $items] {
         append newContent ${item}\n
     }

     return $newContent
 }

 proc TodoArchiveCompleted {} {
     regexp -nocase {^(.*) - .*$} [current] totalMatch basePage
     set aPageName "$basePage - [clock format [clock seconds] -format {%Y-%m-%d}]"
     set aPage [pageget $aPageName]
     set section ""

     set cPage [pageget [current]]
     set newCpage ""

     foreach line [split $cPage \n] {
         if {[string match -nocase "* <x>*</x>" $line]} {
             append aPage ${line}
             if {$section != {}} {
                 append aPage " ($section)"
             }
             append aPage \n
         } else {
             regexp -nocase {^=+ (.*) =+$} $line _match section
             append newCpage ${line}\n
         }
     }

     pageset [current] $newCpage
     pageset $aPageName $aPage
 }
 #unTcl

My sample User Menu

 #Tcl
 usermenu {
     "Back"                       {back-page}
     "Forward"                    {forward-page}
     separator                    {}
     "Archive Completed Entries"  {TodoArchiveCompleted}
 }
 #unTcl