Skip to content

Instantly share code, notes, and snippets.

@cbowdon
Created January 14, 2016 22:06
Show Gist options
  • Save cbowdon/e5f52761a50da552c92c to your computer and use it in GitHub Desktop.
Save cbowdon/e5f52761a50da552c92c to your computer and use it in GitHub Desktop.
Some lisp helper functions for doing XPATH-like queries on org-mode files
(defun org-element-path (path list-of-asts)
"Select all contents of LIST-OF-ASTS matching PATH"
(message (format "%s" path))
(defun --subpath-match (p)
(org-element--select-contents (car p) list-of-asts))
(if (cadr path)
(org-element-path (cdr path) (--subpath-match path))
(--subpath-match path)))
(defun --flatten (list-of-lists)
"Flatten a LIST-OF-LISTS into one list"
(apply 'seq-concatenate 'list list-of-lists))
(defun org-element--all-contents (list-of-asts)
"Get a flat list of the contents of all ASTs in LIST-OF-ASTS"
(--flatten (seq-map 'org-element-contents list-of-asts)))
(defun org-element--type-eq (type element)
"Test whether ELEMENT is of TYPE"
(eq type (org-element-type element)))
(defun org-element--select-contents (descriptor list-of-asts)
"Selector all contents of ASTs in LIST-OF-ASTS matching DESCRIPTOR"
(cond ((and (symbolp descriptor)
(string-prefix-p ":" (symbol-name descriptor)))
(seq-map (lambda (x) (org-element-property descriptor x)) list-of-asts))
(t (org-element--contents-of-type descriptor list-of-asts))))
(defun org-element--filter-contents (pred list-of-asts)
"Filter all contents of ASTs in LIST-OF-ASTS by PRED"
(seq-filter pred
(org-element--all-contents list-of-asts)))
(defun org-element--contents-of-type (type list-of-asts)
"Select all contents of ASTs in LIST-OF-ASTS matching TYPE"
(org-element--filter-contents
(lambda (c) (org-element--type-eq type c))
list-of-asts))
;; For example if the file was:
;; * Lisp
;;
;; #+NAME: foo
;; #+BEGIN_SRC emacs-lisp
;; "test 1"
;; #+END_SRC
;;
;; #+NAME: bar
;; #+BEGIN_SRC emacs-lisp
;; "test 2"
;; #+END_SRC
;;
;; then
(org-element-path '(headline section src-block :name) (list (org-element-parse-buffer)))
;; would return
;; ("foo" "bar")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment