org: Using the mapping API
A.12 Using the mapping API
==========================
Org has sophisticated mapping capabilities to find all entries
satisfying certain criteria. Internally, this functionality is used to
produce agenda views, but there is also an API that can be used to
execute arbitrary functions for each or selected entries. The main
entry point for this API is:
-- Function: org-map-entries func &optional match scope &rest skip
Call ‘FUNC’ at each headline selected by ‘MATCH’ in ‘SCOPE’.
‘FUNC’ is a function or a Lisp form. The function will be called
without arguments, with the cursor positioned at the beginning of
the headline. The return values of all calls to the function will
be collected and returned as a list.
The call to ‘FUNC’ will be wrapped into a save-excursion form, so
‘FUNC’ does not need to preserve point. After evaluation, the
cursor will be moved to the end of the line (presumably of the
headline of the processed entry) and search continues from there.
Under some circumstances, this may not produce the wanted results.
For example, if you have removed (e.g., archived) the current
(sub)tree it could mean that the next entry will be skipped
entirely. In such cases, you can specify the position from where
search should continue by making ‘FUNC’ set the variable
‘org-map-continue-from’ to the desired buffer position.
‘MATCH’ is a tags/property/todo match as it is used in the agenda
match view. Only headlines that are matched by this query will be
considered during the iteration. When ‘MATCH’ is ‘nil’ or ‘t’, all
headlines will be visited by the iteration.
‘SCOPE’ determines the scope of this command. It can be any of:
nil the current buffer, respecting the restriction if any
tree the subtree started with the entry at point
region The entries within the active region, if any
file the current buffer, without restriction
file-with-archives
the current buffer, and any archives associated with it
agenda all agenda files
agenda-with-archives
all agenda files with any archive files associated with them
(file1 file2 ...)
if this is a list, all files in the list will be scanned
The remaining args are treated as settings for the skipping
facilities of the scanner. The following items can be given here:
archive skip trees with the archive tag
comment skip trees with the COMMENT keyword
function or Lisp form
will be used as value for ‘org-agenda-skip-function’,
so whenever the function returns t, FUNC
will not be called for that entry and search will
continue from the point where the function leaves it
The function given to that mapping routine can really do anything you
like. It can use the property API (Using the property API) to
gather more information about the entry, or in order to change metadata
in the entry. Here are a couple of functions that might be handy:
-- Function: org-todo &optional arg
Change the TODO state of the entry. See the docstring of the
functions for the many possible values for the argument ‘ARG’.
-- Function: org-priority &optional action
Change the priority of the entry. See the docstring of this
function for the possible values for ‘ACTION’.
-- Function: org-toggle-tag tag &optional onoff
Toggle the tag ‘TAG’ in the current entry. Setting ‘ONOFF’ to
either ‘on’ or ‘off’ will not toggle tag, but ensure that it is
either on or off.
-- Function: org-promote
Promote the current entry.
-- Function: org-demote
Demote the current entry.
Here is a simple example that will turn all entries in the current
file with a tag ‘TOMORROW’ into TODO entries with the keyword
‘UPCOMING’. Entries in comment trees and in archive trees will be
ignored.
(org-map-entries
'(org-todo "UPCOMING")
"+TOMORROW" 'file 'archive 'comment)
The following example counts the number of entries with TODO keyword
‘WAITING’, in all agenda files.
(length (org-map-entries t "/+WAITING" 'agenda))