Function: org-columns--compute-spec
org-columns--compute-spec is a byte-compiled function defined in
org-colview.el.gz.
Signature
(org-columns--compute-spec SPEC &optional UPDATE)
Documentation
Update tree according to SPEC.
SPEC is a column format specification. When optional argument UPDATE is non-nil, summarized values can replace existing ones in properties drawers.
Source Code
;; Defined in /usr/src/emacs/lisp/org/org-colview.el.gz
(defun org-columns--compute-spec (spec &optional update)
"Update tree according to SPEC.
SPEC is a column format specification. When optional argument
UPDATE is non-nil, summarized values can replace existing ones in
properties drawers."
(let* ((lmax (if (bound-and-true-p org-inlinetask-max-level)
org-inlinetask-max-level
29)) ;Hard-code deepest level.
(lvals (make-vector (1+ lmax) nil))
(level 0)
(inminlevel lmax)
(last-level lmax)
(property (car spec))
(printf (nth 4 spec))
;; Special properties cannot be collected nor summarized, as
;; they have their own way to be computed. Therefore, ignore
;; any operator attached to them.
(operator (and (not (member property org-special-properties))
(nth 3 spec)))
(collect (and operator (org-columns--collect operator)))
(summarize (and operator (org-columns--summarize operator))))
(org-with-wide-buffer
;; Find the region to compute.
(goto-char org-columns-top-level-marker)
(goto-char (condition-case nil (org-end-of-subtree t) (error (point-max))))
;; Walk the tree from the back and do the computations.
(while (re-search-backward
org-outline-regexp-bol org-columns-top-level-marker t)
(unless (or (= level 0) (eq level inminlevel))
(setq last-level level))
(setq level (org-reduced-level (org-outline-level)))
(let* ((pos (match-beginning 0))
(value (if collect (funcall collect property)
(org-entry-get (point) property)))
(value-set (org-string-nw-p value)))
(cond
((< level last-level)
;; Collect values from lower levels and inline tasks here
;; and summarize them using SUMMARIZE. Store them in text
;; property `org-summaries', in alist whose key is SPEC.
(let* ((summary
(and summarize
(let ((values
(cl-loop for l from (1+ level) to lmax
append (aref lvals l))))
(and values (funcall summarize values printf))))))
;; Leaf values are not summaries: do not mark them.
(when summary
(let* ((summaries-alist (get-text-property pos 'org-summaries))
(old (assoc spec summaries-alist)))
(if old (setcdr old summary)
(push (cons spec summary) summaries-alist)
(with-silent-modifications
(add-text-properties
pos (1+ pos) (list 'org-summaries summaries-alist)))))
;; When PROPERTY exists in current node, even if empty,
;; but its value doesn't match the one computed, use
;; the latter instead.
;;
;; Ignore leading or trailing white spaces that might
;; have been introduced in summary, since those are not
;; significant in properties value.
(let ((new-value (org-trim summary)))
(when (and update value (not (equal value new-value)))
(org-entry-put (point) property new-value))))
;; Add current to current level accumulator.
(when (or summary value-set)
(push (or summary value) (aref lvals level)))
;; Clear accumulators for deeper levels.
(cl-loop for l from (1+ level) to lmax do (aset lvals l nil))))
(value-set (push value (aref lvals level)))
(t nil)))))))