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-min-level)
		   org-inlinetask-min-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 (append (and (/= last-level inminlevel)
						   (aref lvals last-level))
					      (aref lvals inminlevel))))
			  (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)))))))