From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Miguel A. Figueroa-Villanueva" Subject: Patch to support nested checkbox statistics. Date: Thu, 20 Dec 2007 14:05:03 -0400 Message-ID: <17f71bca0712201005s4079dddcqce0a7fb252017217@mail.gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Return-path: Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1J5Pla-0001kO-Gw for emacs-orgmode@gnu.org; Thu, 20 Dec 2007 13:05:06 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1J5PlZ-0001hj-Dm for emacs-orgmode@gnu.org; Thu, 20 Dec 2007 13:05:05 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1J5PlZ-0001hY-8N for emacs-orgmode@gnu.org; Thu, 20 Dec 2007 13:05:05 -0500 Received: from ug-out-1314.google.com ([66.249.92.171]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1J5PlY-0004Dj-MF for emacs-orgmode@gnu.org; Thu, 20 Dec 2007 13:05:05 -0500 Received: by ug-out-1314.google.com with SMTP id a2so555524ugf.48 for ; Thu, 20 Dec 2007 10:05:03 -0800 (PST) Content-Disposition: inline List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: emacs-orgmode@gnu.org Hello all, I have implemented the change below to my org.el file to support nested checkbox statistics computation. That is, I can have things like this: ** General Tasks [1/4] SCHEDULED: <2007-12-19 Wed> - [ ] Simple task 1. - [-] Complex task with sub-items. Dash for partially complete. [1/2] - [X] subtask 1 - [ ] subtask 2 - [ ] Simple task 2. - [X] Complex task 2: [2/2] - [X] subtask 1 - [X] subtask 2 - [ ] Complex task 3: [0/2] - [ ] subtask 1 - [ ] subtask 2 All the counts are updated automatically with the function below. Also, if the item that has a count also has a checkbox it will update the status according to it's sub-tasks (none ' ', partial '-', complete 'X'). Hope this finds its way into the org distribution :) --Miguel ------------ (defun org-update-checkbox-count (&optional all) "Update the checkbox statistics in the current section. This will find all statistic cookies like [57%] and [6/12] and update them with the current numbers. With optional prefix argument ALL, do this for the whole buffer." (interactive "P") (save-excursion (let* ((buffer-invisibility-spec (org-inhibit-invisibility)) ; Emacs 21 (beg (condition-case nil (progn (outline-back-to-heading) (point)) (error (point-min)))) (end (move-marker (make-marker) (progn (outline-next-heading) (point)))) (re "\\(\\[[0-9]*%\\]\\)\\|\\(\\[[0-9]*/[0-9]*\\]\\)") (re-box "^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) +\\(\\[[- X]\\]\\)") beg-cookie end-cookie is-percent c-on c-off lim eline curr-ind next-ind (cstat 0) ) (when all (goto-char (point-min)) (outline-next-heading) (setq beg (point) end (point-max))) (goto-char end) ;; find each statistic cookie (while (re-search-backward re beg t) (setq cstat (1+ cstat) beg-cookie (match-beginning 0) end-cookie (match-end 0) is-percent (match-beginning 1) lim (cond ((org-on-heading-p) (outline-next-heading) (point)) ((org-at-item-p) (org-end-of-item) (point)) (t nil)) c-on 0 c-off 0 ) (when lim ;; find first checkbox for this cookie and gather ;; statistics from all that are at this indentation level (goto-char end-cookie) (if (re-search-forward re-box lim t) (progn (org-beginning-of-item) (setq curr-ind (org-get-indentation)) (setq next-ind curr-ind) (while (= curr-ind next-ind) (save-excursion (end-of-line) (setq eline (point))) (if (re-search-forward re-box eline t) (if (member (match-string 2) '("[ ]" "[-]")) (setq c-off (1+ c-off)) (setq c-on (1+ c-on)) ) ) (org-end-of-item) (setq next-ind (org-get-indentation)) ))) ;; update cookie (delete-region beg-cookie end-cookie) (goto-char beg-cookie) (insert (if is-percent (format "[%d%%]" (/ (* 100 c-on) (max 1 (+ c-on c-off)))) (format "[%d/%d]" c-on (+ c-on c-off)))) ;; update items checkbox if it has one (when (org-at-item-p) (org-beginning-of-item) (save-excursion (end-of-line) (setq eline (point))) (when (re-search-forward re-box eline t) (setq beg-cookie (match-beginning 2) end-cookie (match-end 2)) (delete-region beg-cookie end-cookie) (goto-char beg-cookie) (cond ((= c-off 0) (insert "[X]")) ((= c-on 0) (insert "[ ]")) (t (insert "[-]"))) ))) (goto-char beg-cookie) ) (when (interactive-p) (message "Checkbox satistics updated %s (%d places)" (if all "in entire file" "in current outline entry") cstat)))))