(require 'json) (require 'org-element) (defun eth/getAttachmentMails (examName) (unless (derived-mode-p 'org-mode) (error "This command must be run in an org-mode buffer") ) (let ( (contents-list '()) ) (org-map-entries (lambda () ;; Inside this lambda, we are positioned at a matching headline. (let ( (addr (org-entry-get (point) "emailAddress")) (name (org-entry-get (point) "emailName")) (vocative (org-entry-get (point) "emailVocative")) (filename nil) ) (catch 'found (org-map-entries (lambda () (let ( (heading-text (org-get-heading t t)) ) (when (string-match (format "\\[\\[file:\\([^]]+\\)\\]\\[%s\\]\\]" examName) heading-text) (setq filename (concat (file-name-directory buffer-file-name) "/" (match-string 1 heading-text))) (throw 'found t))) ;; Throw to the 'found tag to exit this inner map. ) t ;; Match all headings in the subtree. 'tree) ;; Scope the search to the current subtree. ) (when filename (push (vector addr name vocative filename) contents-list))) ) "emailAddress={.+}" ;; match entries with properties satisfying given regexp 'file) ;; Because we use `push`, the list is built in reverse order. (let ((json-output (json-encode (nreverse contents-list)))) json-output )) )