I am attempting to map over all org entries in a file and collect a part of the heading if it is matched by some regex.
The problem is that string-match always returns nil. I can see that everything else is working correctly as I step through with edebug.
Here I have reduced the problem as far as I can:
(defun test ()
(let ((found nil))
(org-map-entries (lambda ()
(let ((heading (org-get-heading t t)))
(when (string-match "[ \t]*>>>[ \t]*\\([A-Z0-9_-]+\\)"
heading)
(push (match-string 1 heading) found))))
nil '("test.org"))
found))
The 3 lines in test.org:
* >>> one
* two
* >>> three
string-match works fine otherwise:
(string-match "[ \t]*>>>[ \t]*\\([A-Z0-9_-]+\\)" ">>> one")
=> 0
Some things I have attempted:
- Removing string properties before matching.
- Implementing around re-search-forward instead.
- Moving the regex matching to a separate function.
- replaced 'org-map-entries' with 'mapcar' and tested it over a list, works fine.
I'm using GNU Emacs 24.3.1 (x86_64-unknown-linux-gnu, GTK+ Version 3.4.2)
Any tips would be much appreciated.
Could it simply be that case-fold-search
somehow gets set to nil
while that code is running (hence the "A-Z" doesn't match lower case characters any more)? If so, replacing A-Z0-9
with [:alnum:]
should fix it.
Tip: Use org-element
! At least if using Org v8+ is feasible.
Here's a toy example that you can build upon. Copy it to an Org buffer and evaluate the code blocks.
Edit: more examples. Basically, I can't reproduce. See the last heading for your test
function.
* >>> one
#+begin_src emacs-lisp :file test2.org
(save-excursion (find-file "test2.org")
(delete-region (point-min) (point-max))
(insert "* >>> one2\n* two2"))
#+end_src
#+RESULTS:
[[file:test2.org]]
A function
#+begin_src emacs-lisp
(defun my/tagged-headings (&optional regexp file full-element)
"Return headings matching regexp. If simple is t return only the headline. Else return the element. Requires Org-Element (Org>8)"
(require 'org-element)
(save-excursion
(when (and file (file-exists-p file))
(find-file file))
(let (found
(regexp (if regexp regexp "^>>>")))
(org-element-map
(org-element-parse-buffer)
'headline
'(lambda (h)
(when (string-match "^>>>" (org-element-property :raw-value h))
(push (if full-element h (org-element-property :raw-value h)) found))))
found)))
#+end_src
#+begin_src emacs-lisp
(my/tagged-headings)
#+end_src
#+RESULTS:
| >>> three | >>> one |
#+begin_src emacs-lisp
(my/tagged-headings nil "test2.org")
#+end_src
#+RESULTS:
| >>> one2 |
* two
#+begin_src emacs-lisp
(defun my/tagged-headings2 ()
(let (found)
(org-map-entries (lambda ()
(save-excursion
(when (search-forward-regexp "^*+[[:space:]]*>+" (point-at-eol) t)
(push (org-get-heading t t) found)
))))
found))
#+end_src
#+begin_src emacs-lisp
(my/tagged-headings2)
#+end_src
#+RESULTS:
| >>> three | >>> one |
* >>> three
#+begin_src emacs-lisp
(defun test (&optional file)
(save-excursion
(when (and file (file-exists-p file)) (find-file file))
(let ((found nil))
(org-map-entries (lambda ()
(let ((heading (org-get-heading t t)))
(when (string-match "[ \t]*>>>[ \t]*\\([A-Z0-9_-]+\\)"
heading)
(push (match-string 1 heading) found)))))
found)))
#+end_src
#+begin_src emacs-lisp
(test)
#+end_src
#+RESULTS:
| three | one |
#+begin_src emacs-lisp
(test "test2.org")
#+end_src
#+RESULTS:
| one2 |
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With