[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Orgmode] Patch to support nested checkbox statistics.

From: Miguel A. Figueroa-Villanueva
Subject: [Orgmode] Patch to support nested checkbox statistics.
Date: Thu, 20 Dec 2007 14:05:03 -0400

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 :)


(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")
    (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))
        (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)
                (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))
                  (setq next-ind (org-get-indentation))
          ;; update cookie
          (delete-region beg-cookie end-cookie)
          (goto-char beg-cookie)
           (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)
            (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)))))

reply via email to

[Prev in Thread] Current Thread [Next in Thread]