Browse Source

Completing the mapping API.

This is documented in the new appendix "Using the mapping API".
Carsten Dominik 17 năm trước cách đây
mục cha
commit
e3132e37b7
4 tập tin đã thay đổi với 136 bổ sung19 xóa
  1. 4 0
      doc/ChangeLog
  2. 103 3
      doc/org.texi
  3. 2 0
      lisp/ChangeLog
  4. 27 16
      lisp/org.el

+ 4 - 0
doc/ChangeLog

@@ -1,3 +1,7 @@
+2008-06-11  Carsten Dominik  <dominik@science.uva.nl>
+
+	* org.texi (Using the mapping API): New section.
+
 2008-04-15  Jason Riedy  <jason@acm.org>
 
 	* org.texi (A LaTeX example): Note that fmt may be a one-argument

+ 103 - 3
doc/org.texi

@@ -365,6 +365,7 @@ Hacking
 * Dynamic blocks::              Automatically filled blocks
 * Special agenda views::        Customized views
 * Using the property API::      Writing programs that use entry properties
+* Using the mapping API::       Mapping over all or selected entries
 
 Tables and lists in arbitrary syntax
 
@@ -8588,6 +8589,7 @@ Org.
 * Dynamic blocks::              Automatically filled blocks
 * Special agenda views::        Customized views
 * Using the property API::      Writing programs that use entry properties
+* Using the mapping API::       Mapping over all or selected entries
 @end menu
 
 @node Adding hyperlink types, Tables in arbitrary syntax, Hacking, Hacking
@@ -9160,7 +9162,7 @@ like this, even without defining a special function:
     (org-agenda-overriding-header "Projects waiting for something: "))))
 @end lisp
 
-@node Using the property API,  , Special agenda views, Hacking
+@node Using the property API, Using the mapping API, Special agenda views, Hacking
 @section Using the property API
 @cindex API, for properties
 @cindex properties, API
@@ -9218,6 +9220,104 @@ Treat the value of the property PROPERTY as a whitespace-separated list of
 values and check if VALUE is in this list.
 @end defun
 
+@node Using the mapping API,  , Using the property API, Hacking
+@section Using the mapping API
+@cindex API, for mapping
+@cindex mapping entries, 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: 
+
+@defun 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.
+
+MATCH is a tags/property/todo match as it is used in the agenda tags 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:
+
+@example
+nil     @r{the current buffer, respecting the restriction if any}
+tree    @r{the subtree started with the entry at point}
+file    @r{the current buffer, without restriction}
+file-with-archives
+        @r{the current buffer, and any archives associated with it}
+agenda  @r{all agenda files}
+agenda-with-archives
+        @r{all agenda files with any archive files associated with them}
+(file1 file2 ...)
+        @r{if this is a list, all files in the list will be scanned}
+@end example
+
+The remaining args are treated as settings for the skipping facilities of
+the scanner.  The following items can be given here:
+
+@example
+archive   @r{skip trees with the archive tag}
+comment   @r{skip trees with the COMMENT keyword}
+function or Lisp form
+          @r{will be used as value for @code{org-agenda-skip-function},}
+          @r{so whenever the the function returns t, FUNC}
+          @r{will not be called for that entry and search will}
+          @r{continue from the point where the function leaves it}
+@end example
+@end defun
+
+The function given to that mapping routine can really do anything you like.
+It can uce the property API (@pxref{Using the property API}) to gather more
+information about the entry, or in order to change metadate in the entry.
+Here are a couple of functions that might be handy:
+ 
+@defun 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.
+@end defun
+
+@defun org-priority &optional action
+Change the priority of the entry, see the docstring of this function for the
+possible values for ACTION.
+@end defun
+
+@defun org-toggle-tag tag &optional onoff
+Toggle the tag TAG in the current entry.  Setting ONOFF to either @code{on}
+or @code{off} will not toggle tag, but ensure that it is either on or off.
+@end defun
+
+@defun org-promote
+Promote the current entry.
+@end defun
+
+@defun org-demote
+Demote the current entry.
+@end defun
+
+Here is a simple example that will turn all entries in the current file with
+a tag @code{TOMORROW} into TODO entries with the keyword @code{UPCOMING}
+Entries in comment trees and in archive trees will be ignored.
+
+@lisp
+(org-map-entries
+   '(org-todo "UPCOMING")
+   "+TOMORROW" 'file 'archive 'comment)
+@end lisp
+
+The following example counts the number of entries with TODO keyword
+@code{WAITING}, in all agenda files.
+
+@lisp
+(length (org-map-entries t nil 'agenda))
+@end lisp
+
 @node History and Acknowledgments, Main Index, Hacking, Top
 @appendix History and Acknowledgments
 @cindex acknowledgments
@@ -9381,8 +9481,8 @@ subtrees.
 @item
 @i{Dale Smith} proposed link abbreviations.
 @item
-@i{Adam Spiers} asked for global linking commands and inspired the link
-extension system.  support mairix.
+@i{Adam Spiers} asked for global linking commands, inspired the link
+extension system, added support for mairix, and proposed the mapping API.
 @item
 @i{David O'Toole} wrote @file{org-publish.el} and drafted the manual
 chapter about publishing.

+ 2 - 0
lisp/ChangeLog

@@ -1,5 +1,7 @@
 2008-06-11  Carsten Dominik  <dominik@science.uva.nl>
 
+	* org.el (org-scan-tags): Allow new values for ACTION parameter.
+
 	* org-remember.el (org-remember-templates): Fix bug in
 	customization type definition.
 

+ 27 - 16
lisp/org.el

@@ -9177,8 +9177,12 @@ ACTION can be `set', `up', `down', or a character."
 
 (defun org-scan-tags (action matcher &optional todo-only)
   "Scan headline tags with inheritance and produce output ACTION.
-ACTION can be `sparse-tree' or `agenda'.  It can also be a Lisp form
-or a function that should be called at each matched headline.
+
+ACTION can be `sparse-tree' to produce a sparse tree in the current buffer,
+or `agenda' to produce an entry list for an agenda view.  It can also be
+a Lisp form or a function that should be called at each matched headline, in
+this case the return value is a list of all return values from these calls.
+
 MATCHER is a Lisp form to be evaluated, testing if a given set of tags
 qualifies a headline for inclusion.  When TODO-ONLY is non-nil,
 only lines with a TODO keyword are included in the output."
@@ -9203,7 +9207,8 @@ only lines with a TODO keyword are included in the output."
 	 (tags-alist (list (cons 0 (mapcar 'downcase org-file-tags))))
 	 (llast 0) rtn level category i txt
 	 todo marker entry priority)
-    (when (listp action) (setq action (list 'lambda nil action)))
+    (when (not (member action '(agenda sparse-tree)))
+      (setq action (list 'lambda nil action)))
     (save-excursion
       (goto-char (point-min))
       (when (eq action 'sparse-tree)
@@ -9268,7 +9273,8 @@ only lines with a TODO keyword are included in the output."
 		'priority priority 'type "tagsmatch")
 	      (push txt rtn))
 	     ((functionp action)
-	      (save-excursion (push (funcall action) rtn))
+	      (save-excursion
+		(push (let (post-command-hook) (funcall action) rtn)))
 	      (goto-char (point-at-eol)))
 	     (t (error "Invalid action")))
 
@@ -9936,35 +9942,40 @@ Returns the new tags string, or nil to not change the current settings."
 ;;;###autoload
 (defun 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.
+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.
+
 MATCH is a tags/property/todo match as it is used in the agenda tags 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:
 
-tree    The subtree started with the entry at point
 nil     The current buffer, respecting the restriction if any
+tree    The subtree started with the entry at point
 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
-list of files
+\(file1 file2 ...)
         If this is a list, all files in the list will be scanned
 
-SKIP is a list of symbols that can select the skipping facilities of the
-agenda to skip certain entries and trees.  The following items are allowed
-here:
+The remaining args are treated as settings for the skipping facilities of
+the scanner.  The following items can be given here:
 
-  the symbol `archive':   skip trees with the archive tag.
-  the symbol `comment':   skip trees with the COMMENT keyword
-  function or Lisp form:  will be used as value for `org-agenda-skip-function',
-                          so whenever the the function returns t, FUNC
-                          will not be called for that entry and search will
-                          continue from the point where the function leaves it."
+  archive    skip trees with the archive tag.
+  comment    skip trees with the COMMENT keyword
+  function or Emacs Lisp form:
+             will be used as value for `org-agenda-skip-function', so whenever
+             the the function returns t, FUNC will not be called for that
+             entry and search will continue from the point where the
+             function leaves it."
   (let* ((org-agenda-skip-archived-trees (memq 'archive skip))
 	 (org-agenda-skip-comment-trees (memq 'comment skip))
 	 (org-agenda-skip-function