Function: org-update-checkbox-count
org-update-checkbox-count is an interactive and byte-compiled function
defined in org-list.el.gz.
Signature
(org-update-checkbox-count &optional ALL)
Documentation
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.
Key Bindings
Source Code
;; Defined in /usr/src/emacs/lisp/org/org-list.el.gz
(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")
(org-with-wide-buffer
(let* ((cookie-re "\\(\\(\\[[0-9]*%\\]\\)\\|\\(\\[[0-9]*/[0-9]*\\]\\)\\)")
(box-re "^[ \t]*\\([-+*]\\|\\([0-9]+\\|[A-Za-z]\\)[.)]\\)[ \t]+\
\\(?:\\[@\\(?:start:\\)?\\([0-9]+\\|[A-Za-z]\\)\\][ \t]*\\)?\\(\\[[- X]\\]\\)")
(cookie-data (or (org-entry-get nil "COOKIE_DATA") ""))
(recursivep
(or (not org-checkbox-hierarchical-statistics)
(string-match-p "\\<recursive\\>" cookie-data)))
(within-inlinetask (and (not all)
(featurep 'org-inlinetask)
(org-inlinetask-in-task-p)))
(end (cond (all (point-max))
(within-inlinetask
(save-excursion (outline-next-heading) (point)))
(t (save-excursion
(org-with-limited-levels (outline-next-heading))
(point)))))
(count-boxes
(lambda (item structs recursivep)
;; Return number of checked boxes and boxes of all types
;; in all structures in STRUCTS. If RECURSIVEP is
;; non-nil, also count boxes in sub-lists. If ITEM is
;; nil, count across the whole structure, else count only
;; across subtree whose ancestor is ITEM.
(let ((c-on 0) (c-all 0))
(dolist (s structs (list c-on c-all))
(let* ((pre (org-list-prevs-alist s))
(par (org-list-parents-alist s))
(items
(cond
((and recursivep item) (org-list-get-subtree item s))
(recursivep (mapcar #'car s))
(item (org-list-get-children item s par))
(t (org-list-get-all-items
(org-list-get-top-point s) s pre))))
(cookies (delq nil (mapcar
(lambda (e)
(org-list-get-checkbox e s))
items))))
(cl-incf c-all (length cookies))
(cl-incf c-on (cl-count "[X]" cookies :test #'equal)))))))
cookies-list cache)
;; Move to start.
(cond (all (goto-char (point-min)))
(within-inlinetask (org-back-to-heading t))
(t (org-with-limited-levels (outline-previous-heading))))
;; Build an alist for each cookie found. The key is the position
;; at beginning of cookie and values ending position, format of
;; cookie, number of checked boxes to report and total number of
;; boxes.
(while (re-search-forward cookie-re end t)
(let ((context (save-excursion (backward-char)
(save-match-data (org-element-context)))))
(when (and (eq (org-element-type context) 'statistics-cookie)
(not (string-match-p "\\<todo\\>" cookie-data)))
(push
(append
(list (match-beginning 1) (match-end 1) (match-end 2))
(let* ((container
(org-element-lineage
context
'(drawer center-block dynamic-block inlinetask item
quote-block special-block verse-block)))
(beg (if container
(org-element-property :contents-begin container)
(save-excursion
(org-with-limited-levels
(outline-previous-heading))
(point)))))
(or (cdr (assq beg cache))
(save-excursion
(goto-char beg)
(let ((end
(if container
(org-element-property :contents-end container)
(save-excursion
(org-with-limited-levels (outline-next-heading))
(point))))
structs)
(while (re-search-forward box-re end t)
(let ((element (org-element-at-point)))
(when (eq (org-element-type element) 'item)
(push (org-element-property :structure element)
structs)
;; Skip whole list since we have its
;; structure anyway.
(while (setq element (org-element-lineage
element '(plain-list)))
(goto-char
(min (org-element-property :end element)
end))))))
;; Cache count for cookies applying to the same
;; area. Then return it.
(let ((count
(funcall count-boxes
(and (eq (org-element-type container)
'item)
(org-element-property
:begin container))
structs
recursivep)))
(push (cons beg count) cache)
count))))))
cookies-list))))
;; Apply alist to buffer.
(dolist (cookie cookies-list)
(let* ((beg (car cookie))
(end (nth 1 cookie))
(percent (nth 2 cookie))
(checked (nth 3 cookie))
(total (nth 4 cookie)))
(goto-char beg)
(insert
(if percent (format "[%d%%]" (floor (* 100.0 checked)
(max 1 total)))
(format "[%d/%d]" checked total)))
(delete-region (point) (+ (point) (- end beg)))
(when org-auto-align-tags (org-fix-tags-on-the-fly)))))))