0

Question: How can I retrieve, over a set of files S (in particular: over my agenda files + their archive files) all org-mode headers that are marked "CLOSED" (i.e., have a "CLOSED" stamp like CLOSED: [2019-05-11 Sat 18:11]), so that I may then run an operation over them? My particular use case is to grab all headers that satisfy the above property, so that I can then grab each of their org-property :T:, and sum them together. So for example if I have

# File1
* SATISFICED Header1
  CLOSED: [2019-05-01 Wed 18:13]
:PROPERTIES:
:T: 1
:END:

# File2
* SATISFICED Header2
  CLOSED: [2019-05-11 Sat 18:13]
:PROPERTIES:
:T: 2
:END:
* SATISFICED Header3
  CLOSED: [2019-05-11 Sat 18:13]
:PROPERTIES:
:T: 3
:END:

I'd like to run a function like (sum--all-T-from "[2019-05-10]" "[2019-05-11]") to get as answer 5.

1

First you need a predicate function to determine whether the closed timestamp is within the specified range. If it is and the headline contains a T property, add the value of T to the list and return the sum of all numbers in the list.

(defun timestamp-within-range-p (start-date end-date ts)
  "Non-nil if TS is within START-DATE and END-DATE."
  (or (and (time-less-p
        (org-time-string-to-time start-date)
        (org-time-string-to-time ts))
       (time-less-p
        (org-time-string-to-time ts)
        (org-time-string-to-time end-date)))
      (equal (format-time-string "[%F]" (org-time-string-to-time ts))
         start-date)
      (equal (format-time-string "[%F]" (org-time-string-to-time ts))
         end-date)))

(defun sum--all-T-from (start-date end-date)
  (let (closed)
    (org-map-entries
     (lambda ()
       (when (and (assoc "CLOSED" (org-entry-properties))
                  (org-entry-get nil "T"))
         (let ((ts (assoc-default "CLOSED" (org-entry-properties))))
           (when (timestamp-within-range-p start-date end-date ts)
             (push (string-to-number (org-entry-get nil "T")) closed)))))
     nil 'agenda-with-archives)
    (apply '+ closed)))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.