kanban.el

(Arne Babenhauserheide)
2012-04-24: Added stateful kanban and docstrings. fluss

Added stateful kanban and docstrings.

diff --git a/kanban.el b/kanban.el
--- a/kanban.el
+++ b/kanban.el
@@ -8,7 +8,7 @@
 ;; |---+---+---|
 ;; |   |   |   |
 ;; |   |   |   |
-;; #+TBLFM: @1='(kanban-zero-headers $#)::@2$1..@>$>='(kanban-zero $# @#)
+;; #+TBLFM: @1='(kanban-headers $#)::@2$1..@>$>='(kanban-zero $# @#)
 ;;
 ;; * Stateful Kanban: Use org-mode to retrieve tasks, but track their state in the Kanban board
 ;;
@@ -16,13 +16,20 @@
 ;; |---+---+---|
 ;; |   |   |   |
 ;; |   |   |   |
-;; #+TBLFM: $1='(let ((elem (nth (- @# 1) (delete nil (org-map-entries (lambda () (let ((line (filter-buffer-substring (point) (line-end-position)))(keyword "❢")) (let ((cleanline (nth 1 (split-string line "* ")))) (let ((shortline (substring cleanline (+ (length keyword) 1) (min 40 (length cleanline))))) (let ((clean (if (member " " (split-string (substring shortline (min 25 (length shortline))) "")) (mapconcat 'identity (reverse (rest (reverse (split-string shortline " ")))) " ") shortline))) (if (not (member keyword (split-string cleanline " "))) nil (concat "[[" cleanline "][" clean "]]" ))))))) nil 'agenda))))) (if (member elem (list @2$2..@>$>)) "" elem))::$2='(let ((elem (nth (- @# 1) (delete nil (org-map-entries (lambda () (let ((line (filter-buffer-substring (point) (line-end-position)))(keyword "STARTED")) (let ((cleanline (nth 1 (split-string line "* ")))) (if (not (member keyword (split-string cleanline " "))) nil (concat "[[" cleanline "][" (substring cleanline (+ (length keyword) 1) (min 40 (length cleanline))) "]]" ))))) nil 'agenda))))) (if (member elem (list @2$3..@>$>)) "" (if (equal elem nil) "" elem)))::@1='(let ((words org-todo-keywords-1)) (nth (- $# 1) words))
+;; #+TBLFM: (kanban-headers $#)::@2$1..@>$>='(kanban @# @2$2..@>$>)
 
 
-(defun kanban-zero-headers (column)
+(defun kanban-headers (column)
+  "Fill the headers of your table with your org-mode TODO
+states. If the table is too narrow, the only the first n TODO
+states will be shown, with n as the number of columns in your
+table."
   (let ((words org-todo-keywords-1)) (nth (- column 1) words)))
 
 (defun kanban-zero (column row)
+  "Zero-state Kanban board: This Kanban board just displays all
+org-mode headers which have a TODO state in their respective TODO
+state. Useful for getting a simple overview of your tasks."
   (let
       ((elem (nth (- column 1) 
                   (delete nil (org-map-entries
@@ -39,4 +46,36 @@
                                                           (min 30 (length cleanline))) "]]" ))))) nil 'agenda)))))
     (if
         (equal
-         elem nil) "" elem)))
\ No newline at end of file
+         elem nil) "" elem)))
+
+(defun kanban (column cels)
+  "Kanban TODO item grabber. Fills the first row of the kanban
+table with org-mode TODO entries, if they are not in another cell
+of the table. This allows you to set the state manually and just
+use org-mode to supply new TODO entries."
+ (let ((elem (nth (- column 1) (delete nil
+                                   (org-map-entries
+                                    (lambda
+                                      ()
+                                      (let
+                                          ((line (filter-buffer-substring (point) (line-end-position)))
+                                           (keyword "❢"))
+                                        (let ((cleanline (nth 1 (split-string line "* "))))
+                                          (let ((shortline (substring cleanline 
+                                                                      (+ (length keyword) 1) 
+                                                                      (min 40 (length cleanline)))))
+                                            (let ((clean (if (member " " (split-string 
+                                                                          (substring shortline 
+                                                                                     (min 25 (length shortline)))
+                                                                          ""))
+                                                             (mapconcat 'identity 
+                                                                        (reverse (rest (reverse 
+                                                                                        (split-string shortline " "))))
+                                                                        " ") shortline)))
+                                              (if (not (member keyword (split-string cleanline " "))) 
+                                                  nil
+                                                (concat "[[" cleanline "][" clean "]]" )))))))
+                                    nil 'agenda)))))
+   (if
+       (member elem
+               (list cels)) "" elem)))