emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master 5cacf20 078/135: Updated documentation


From: Ian Dunn
Subject: [elpa] master 5cacf20 078/135: Updated documentation
Date: Mon, 17 Feb 2020 10:52:56 -0500 (EST)

branch: master
commit 5cacf20b153a7da664ab846efd20ff63449a4bb6
Author: Ian Dunn <address@hidden>
Commit: Ian Dunn <address@hidden>

    Updated documentation
    
    Including info and dir pages for use in ELPA.
    
    * org-edna.el: Added docstrings for all finders, actions, and conditions.
    
    * org-edna.org: Updated documentation to fix uses of commas vs. spaces in 
syntax.
      (Contributing): Give a little background on bazaar and how to use it.
---
 .bzrignore    |    1 -
 dir           |   19 +
 org-edna.el   |  362 +++++++++++++++--
 org-edna.info | 1233 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 org-edna.org  |  240 +++++++----
 5 files changed, 1734 insertions(+), 121 deletions(-)

diff --git a/.bzrignore b/.bzrignore
index ec97837..5228a6a 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -1,6 +1,5 @@
 *.elc
 local.mk
 org-edna-autoloads.el
-org-edna.info
 org-edna.texi
 org-edna.html
\ No newline at end of file
diff --git a/dir b/dir
new file mode 100644
index 0000000..cf49cac
--- /dev/null
+++ b/dir
@@ -0,0 +1,19 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir,     Node: Top       This is the top of the INFO tree
+
+  This (the Directory node) gives a menu of major topics.
+  Typing "q" exits, "H" lists all Info commands, "d" returns here,
+  "h" gives a primer for first-timers,
+  "mEmacs<Return>" visits the Emacs manual, etc.
+
+  In Emacs, you can click mouse button 2 on a menu item or cross reference
+  to select it.
+
+* Menu:
+
+Emacs
+* Org Edna: (org-edna).         Extensible Dependencies ’N’ Actions for 
+                                  Org Mode tasks.
diff --git a/org-edna.el b/org-edna.el
index bda6ec3..ccee794 100644
--- a/org-edna.el
+++ b/org-edna.el
@@ -29,7 +29,7 @@
 ;; fulfilled before a task can be completed and actions to take once it is.
 
 ;; Org Edna runs when either the BLOCKER or TRIGGER properties are set on a
-;; headline, and when it is changing from a TODO state to a DONE state.
+;; heading, and when it is changing from a TODO state to a DONE state.
 
 ;;; History:
 
@@ -163,7 +163,7 @@ indicating whether FORM accepts actions or conditions."
         (blocking-entry)
         (consideration 'all)
         (state nil) ;; Type of operation
-        ;; Keep track of the current headline
+        ;; Keep track of the current heading
         (last-entry (point-marker))
         (pos 0))
     (while (< pos (length form))
@@ -295,6 +295,8 @@ Remove Edna's workers from `org-trigger-hook' and
 (defun org-edna-finder/match (match-spec &optional scope skip)
   "Find entries using Org matching.
 
+Edna Syntax: match(\"MATCH-SPEC\" SCOPE SKIP)
+
 MATCH-SPEC may be any valid match string; it is passed straight
 into `org-map-entries'.
 
@@ -316,15 +318,28 @@ SCOPE defaults to agenda, and SKIP defaults to nil.
 
 ;; ID finder
 (defun org-edna-finder/ids (&rest ids)
-  "Find a list of headlines with given IDs.
+  "Find a list of headings with given IDs.
+
+Edna Syntax: ids(ID1 ID2 ...)
+
+Each ID is a UUID as understood by `org-id-find'.
 
-IDS are all UUIDs as understood by `org-id-find'."
+Note that in the edna syntax, the IDs don't need to be quoted."
   (mapcar (lambda (id) (org-id-find id 'marker)) ids))
 
 (defun org-edna-finder/self ()
+  "Finder for the current heading.
+
+Edna Syntax: self"
   (list (point-marker)))
 
 (defun org-edna-finder/siblings ()
+  "Finder for all siblings of the source heading.
+
+Edna Syntax: siblings
+
+Siblings are returned in order, starting from the first heading,
+and ignoring the source heading."
   (org-with-wide-buffer
    (let ((self (and (ignore-errors (org-back-to-heading t)) (point)))
          (markers))
@@ -338,6 +353,12 @@ IDS are all UUIDs as understood by `org-id-find'."
      (nreverse markers))))
 
 (defun org-edna-finder/siblings-wrap ()
+  "Finder for all siblings of the source heading.
+
+Edna Syntax: siblings-wrap
+
+Siblings are returned in order, starting from the first heading
+after the source heading and wrapping when it reaches the end."
   (org-with-wide-buffer
    (let ((self (and (ignore-errors (org-back-to-heading t)) (point)))
          (markers))
@@ -356,6 +377,12 @@ IDS are all UUIDs as understood by `org-id-find'."
      (nreverse markers))))
 
 (defun org-edna-finder/rest-of-siblings ()
+  "Finder for the siblings after the source heading.
+
+Edna Syntax: rest-of-siblings
+
+Siblings are returned in order, starting from the first heading
+after the source heading."
   (org-with-wide-buffer
    (let ((self (and (ignore-errors (org-back-to-heading t)) (point)))
          (markers))
@@ -366,11 +393,23 @@ IDS are all UUIDs as understood by `org-id-find'."
      (nreverse markers))))
 
 (defun org-edna-finder/next-sibling ()
+  "Finder for the next sibling after the source heading.
+
+Edna Syntax: next-sibling
+
+If the source heading is the last of its siblings, no target is
+returned."
   (org-with-wide-buffer
    (and (org-get-next-sibling)
         (list (point-marker)))))
 
 (defun org-edna-finder/next-sibling-wrap ()
+  "Finder for the next sibling after the source heading.
+
+Edna Syntax: next-sibling-wrap
+
+If the source heading is the last of its siblings, its first
+sibling is returned."
   (org-with-wide-buffer
    (if (org-goto-sibling)
        (list (point-marker))
@@ -379,16 +418,32 @@ IDS are all UUIDs as understood by `org-id-find'."
      (list (point-marker)))))
 
 (defun org-edna-finder/previous-sibling ()
+  "Finder for the first sibling before the source heading.
+
+Edna Syntax: previous-sibling
+
+If the source heading is the first of its siblings, no target is
+returned."
   (org-with-wide-buffer
    (and (org-get-last-sibling)
         (list (point-marker)))))
 
 (defun org-edna-finder/first-child ()
+  "Return the first child of the source heading.
+
+Edna Syntax: first-child
+
+If the source heading has no children, no target is returned."
   (org-with-wide-buffer
    (and (org-goto-first-child)
         (list (point-marker)))))
 
 (defun org-edna-finder/children ()
+  "Finder for the immediate children of the source heading.
+
+Edna Syntax: children
+
+If the source has no children, no target is returned."
   (org-with-wide-buffer
    (let ((markers))
      (org-goto-first-child)
@@ -398,18 +453,32 @@ IDS are all UUIDs as understood by `org-id-find'."
      (nreverse markers))))
 
 (defun org-edna-finder/parent ()
+  "Finder for the parent of the source heading.
+
+Edna Syntax: parent
+
+If the source heading is a top-level heading, no target is
+returned."
   (org-with-wide-buffer
    (and (org-up-heading-safe)
         (list (point-marker)))))
 
 (defun org-edna-finder/descendants ()
+  "Finder for all descendants of the source heading.
+
+Edna Syntax: descendants
+
+This is ALL descendants of the source heading, across all
+levels.  This also includes the source heading."
   (org-with-wide-buffer
    (org-map-entries
     (lambda nil (point-marker))
     nil 'tree)))
 
 (defun org-edna-finder/ancestors ()
-  "Find a list of ancestors.
+  "Finder for the ancestors of the source heading.
+
+Edna Syntax: ancestors
 
 Example:
 
@@ -432,9 +501,12 @@ ignored."
      (nreverse markers))))
 
 (defun org-edna-finder/olp (file olp)
-  "Find a headline by its outline path.
+  "Finder for heading by its outline path.
 
-Finds the heading given by OLP in FILE.  Both arguments are strings.
+Edna Syntax: olp(\"FILE\" \"OLP\")
+
+Finds the heading given by OLP in FILE.  Both arguments are
+strings.  OLP is an outline path.  Example:
 
 * TODO Test
   :PROPERTIES:
@@ -450,42 +522,59 @@ Test will block if the heading \"path/to/heading\" in
 ;; TODO: Clean up the buffer when it's finished
 
 (defun org-edna-finder/file (file)
-  "Find a file by name.
+  "Finder for a file by its name.
+
+Edna Syntax: file(\"FILE\")
 
-The `file' finder finds a single file, specified as a string.
-The returned target will be the minimum point in the file.
+FILE is the full path to the desired file.  The returned target
+will be the minimum point in the file.
 
 * TODO Test
   :PROPERTIES:
   :BLOCKER:  file(\"~/myfile.org\") headings?
   :END:
 
-Here, \"Test\" will block until myfile.org is clear of headlines.
+Here, \"Test\" will block until myfile.org is clear of headings.
 
-Note that with the default condition, `file' won't work."
+Note that this does not give a valid heading, so any conditions
+or actions that require will throw an error.  Consult the
+documentation for individual actions or conditions to determine
+which ones will and won't work."
   ;; If there isn't a buffer visiting file, then there's no point in having a
   ;; marker to the start of the file, so use `find-file-noselect'.
   (with-current-buffer (find-file-noselect file)
     (list (point-min-marker))))
 
 (defun org-edna-finder/org-file (file)
-  "Find a file in `org-directory'.
+  "Finder for FILE in `org-directory'.
+
+Edna Syntax: org-file(\"FILE\")
 
-A special form of `file', `org-file' will find FILE (a string) in
-`org-directory'.
+FILE is the relative path of a file in `org-directory'.  Nested
+files are allowed, such as \"my-directory/my-file.org\".  The
+returned target is the minimum point of FILE.
 
 * TODO Test
   :PROPERTIES:
   :BLOCKER:  org-file(\"test.org\")
   :END:
 
-Note that the file still requires an extension."
+Note that the file still requires an extension; the \"org\" here
+just means to look in `org-directory', not necessarily an
+`org-mode' file.
+
+Note that this does not give a valid heading, so any conditions
+or actions that require will throw an error.  Consult the
+documentation for individual actions or conditions to determine
+which ones will and won't work."
   (with-current-buffer (find-file-noselect (expand-file-name file 
org-directory))
     (list (point-min-marker))))
 
 (defun org-edna-finder/chain-find (&rest options)
   "Find a target as org-depend does.
 
+Edna Syntax: chain-find(OPTION OPTION...)
+
 Identical to the chain argument in org-depend, chain-find selects its single
 target using the following method:
 
@@ -493,17 +582,20 @@ target using the following method:
 2. Filters the targets from Step 1
 3. Sorts the targets from Step 2
 
-After this is finished, chain-find selects the first target in the list and
-returns it.
+After this is finished, chain-find selects the first target in
+the list and returns it.
+
+One option from each of the following three categories may be
+used; if more than one is specified, the last will be used.
+Apart from that, argument order is irrelevant.
 
-One option from each of the following three categories may be used; if more 
than
-one is specified, the last will be used.
+All arguments are symbols.
 
 *Selection*
 
-- from-top:     Select siblings of the current headline, starting at the top
+- from-top:     Select siblings of the current heading, starting at the top
 - from-bottom:  As above, but from the bottom
-- from-current: Selects siblings, starting from the headline (wraps)
+- from-current: Selects siblings, starting from the heading (wraps)
 - no-wrap:      As above, but without wrapping
 
 *Filtering*
@@ -583,13 +675,24 @@ one is specified, the last will be used.
 
 
 ;; Set TODO state
-(defun org-edna-action/todo! (last-entry new-state)
-  (ignore last-entry)
+(defun org-edna-action/todo! (_last-entry new-state)
+  "Action to set a target heading's TODO state to NEW-STATE.
+
+Edna Syntax: todo!(NEW-STATE)
+Edna Syntax: todo!(\"NEW-STATE\")
+
+NEW-STATE may either be a symbol or a string.  If it is a symbol,
+the symbol name is used for the new state.  Otherwise, it is a
+string for the new state, or \"\" to remove the state."
   (org-todo (if (stringp new-state) new-state (symbol-name new-state))))
 
 ;; Set planning info
 
 (defun org-edna--mod-timestamp (time-stamp n what)
+  "Modify the timestamp TIME-STAMP by N WHATs.
+
+N is an integer.  WHAT can be `day', `month', `year', `minute',
+`second'."
   (with-temp-buffer
     (insert time-stamp)
     (goto-char (point-min))
@@ -597,9 +700,13 @@ one is specified, the last will be used.
     (buffer-string)))
 
 (defun org-edna--get-planning-info (what)
+  "Get the planning info for WHAT.
+
+WHAT is either 'scheduled or 'deadline."
   (org-entry-get nil (if (eq what 'scheduled) "SCHEDULED" "DEADLINE")))
 
 (defun org-edna--handle-planning (type last-entry args)
+  "Handle planning of type TYPE."
   ;; Need case-fold-search enabled so org-read-date-get-relative will 
recognize "M"
   (let* ((case-fold-search t)
          (arg (nth 0 args))
@@ -643,51 +750,155 @@ one is specified, the last will be used.
         (org--deadline-or-schedule nil type new-ts))))))
 
 (defun org-edna-action/scheduled! (last-entry &rest args)
+  "Action to set the scheduled time of a target heading based on ARGS.
+
+Edna Syntax: scheduled!(\"DATE[ TIME]\")       [1]
+Edna Syntax: scheduled!(rm|remove)             [2]
+Edna Syntax: scheduled!(cp|copy)               [3]
+Edna Syntax: scheduled!(\"[+|-|++|--]NTHING\") [4]
+
+In form 1, schedule the target for the given date and time.  If
+DATE is a weekday instead of a date, schedule the target for the
+following weekday.  If it is a date, schedule it for that date
+exactly.  TIME is a time string, such as HH:MM.  If it isn't
+specified, only a date will be applied to the target.  Any string
+recognized by `org-read-date' may be used.
+
+Form 2 will remove the scheduled time from the target.
+
+Form 3 will copy the scheduled time from LAST-ENTRY (the current
+heading) to the target.
+
+Form 4 increments(+) or decrements(-) the target's scheduled time
+by N THINGS relative to either itself (+/-) or the current
+time (++/--).  THING is one of y (years), m (months), d (days),
+h (hours), or M (minutes), and N is an integer."
   (org-edna--handle-planning 'scheduled last-entry args))
 
 (defun org-edna-action/deadline! (last-entry &rest args)
+  "Action to set the deadline time of a target heading based on ARGS.
+
+Edna Syntax: deadline!(\"DATE[ TIME]\")       [1]
+Edna Syntax: deadline!(rm|remove)             [2]
+Edna Syntax: deadline!(cp|copy)               [3]
+Edna Syntax: deadline!(\"[+|-|++|--]NTHING\") [4]
+
+In form 1, set the deadline the target for the given date and
+time.  If DATE is a weekday instead of a date, set the deadline
+the target for the following weekday.  If it is a date, set the
+deadline it for that date exactly.  TIME is a time string, such
+as HH:MM.  If it isn't specified, only a date will be applied to
+the target.  Any string recognized by `org-read-date' may be
+used.
+
+Form 2 will remove the deadline time from the target.
+
+Form 3 will copy the deadline time from LAST-ENTRY (the current
+heading) to the target.
+
+Form 4 increments(+) or decrements(-) the target's deadline time
+by N THINGS relative to either itself (+/-) or the current
+time (++/--).  THING is one of y (years), m (months), d (days),
+h (hours), or M (minutes), and N is an integer."
   (org-edna--handle-planning 'deadline last-entry args))
 
-(defun org-edna-action/tag! (last-entry tags)
-  (ignore last-entry)
+(defun org-edna-action/tag! (_last-entry tags)
+  "Action to set the tags of a target heading to TAGS.
+
+Edna Syntax: tag!(\"TAGS\")
+
+TAGS is a valid tag specification, such as \":aa:bb:cc:\"."
   (org-set-tags-to tags))
 
-(defun org-edna-action/set-property! (last-entry property value)
-  (ignore last-entry)
+(defun org-edna-action/set-property! (_last-entry property value)
+  "Action to set the property PROPERTY of a target heading to VALUE.
+
+Edna Syntax: set-property!(\"PROPERTY\" \"VALUE\")
+
+PROPERTY and VALUE are both strings.  PROPERTY must be a valid
+org mode property."
   (org-entry-put nil property value))
 
-(defun org-edna-action/delete-property! (last-entry property)
-  (ignore last-entry)
+(defun org-edna-action/delete-property! (_last-entry property)
+  "Action to delete a property from a target heading.
+
+Edna Syntax: delete-property!(\"PROPERTY\")
+
+PROPERTY must be a valid org mode property."
   (org-entry-delete nil property))
 
-(defun org-edna-action/clock-in! (last-entry)
-  (ignore last-entry)
+(defun org-edna-action/clock-in! (_last-entry)
+  "Action to clock into a target heading.
+
+Edna Syntax: clock-in!"
   (org-clock-in))
 
-(defun org-edna-action/clock-out! (last-entry)
-  (ignore last-entry)
+(defun org-edna-action/clock-out! (_last-entry)
+  "Action to clock out from the current clocked heading.
+
+Edna Syntax: clock-out!
+
+Note that this will not necessarily clock out of the target, but
+the actual running clock."
   (org-clock-out))
 
-(defun org-edna-action/set-priority! (last-entry priority-action)
-  "PRIORITY-ACTION is passed straight to `org-priority'."
-  (ignore last-entry)
+(defun org-edna-action/set-priority! (_last-entry priority-action)
+  "Action to set the priority of a target heading.
+
+Edna Syntax: set-priority!(\"PRIORITY-STRING\") [1]
+Edna Syntax: set-priority!(up)                  [2]
+Edna Syntax: set-priority!(down)                [3]
+Edna Syntax: set-priority!(P)                   [4]
+
+Form 1 sets the priority to PRIORITY-STRING, so PRIORITY-STRING
+must be a valid priority string, such as \"A\" or \"E\".  It may
+also be the string \" \", which removes the priority from the
+target.
+
+Form 2 cycles the target's priority up through the list of
+allowed priorities.
+
+Form 3 cycles the target's priority down through the list of
+allowed priorities.
+
+Form 4: Set the target's priority to the character P."
   (org-priority (if (stringp priority-action)
                     (string-to-char priority-action)
                   priority-action)))
 
-(defun org-edna-action/set-effort! (last-entry value)
-  (ignore last-entry)
+(defun org-edna-action/set-effort! (_last-entry value)
+  "Action to set the effort of a target heading.
+
+Edna Syntax: set-effort!(VALUE)     [1]
+Edna Syntax: set-effort!(increment) [2]
+
+For form 1, set the effort based on VALUE.  If VALUE is a string,
+it's converted to an integer.  Otherwise, the integer is used as
+the raw value for the effort.
+
+For form 2, increment the effort to the next allowed value."
   (if (eq value 'increment)
       (org-set-effort nil value)
     (org-set-effort value nil)))
 
-(defun org-edna-action/archive! (last-entry)
-  (ignore last-entry)
+(defun org-edna-action/archive! (_last-entry)
+  "Action to archive a target heading.
+
+Edna Syntax: archive!
+
+If `org-edna-prompt-for-archive', prompt before archiving the
+entry."
   (if org-edna-prompt-for-archive
       (org-archive-subtree-default-with-confirmation)
     (org-archive-subtree-default)))
 
 (defun org-edna-action/chain! (last-entry property)
+  "Action to copy a property to a target heading.
+
+Edna Syntax: chain!(\"PROPERTY\")
+
+Copy PROPERTY from the source heading to the target heading.
+Does nothing if the source heading has no property PROPERTY."
   (when-let ((old-prop (org-entry-get last-entry property)))
     (org-entry-put nil property old-prop)))
 
@@ -706,6 +917,30 @@ one is specified, the last will be used.
 ;; This means that we want to take the exclusive-or of condition and neg.
 
 (defun org-edna-condition/done? (neg)
+  "Condition to check if all target headings are in the DONE state.
+
+Edna Syntax: done?
+
+DONE state is determined by the local value of
+`org-done-keywords'.
+
+Example:
+
+* TODO Heading
+  :PROPERTIES:
+  :BLOCKER: match(\"target\") done?
+  :END:
+
+Here, \"Heading\" will block if all targets tagged \"target\" are
+in a DONE state.
+
+* TODO Heading 2
+  :PROPERTIES:
+  :BLOCKER: match(\"target\") !done?
+  :END:
+
+Here, \"Heading 2\" will block if all targets tagged \"target\"
+are not in a DONE state."
   (when-let ((condition
               (if neg
                   (member (org-entry-get nil "TODO") org-not-done-keywords)
@@ -713,27 +948,59 @@ one is specified, the last will be used.
     (org-get-heading)))
 
 (defun org-edna-condition/todo-state? (neg state)
+  "Condition to check if all target headings have the TODO state STATE.
+
+Edna Syntax: todo-state?(\"STATE\")
+
+Block the source heading if all target headings have TODO state
+STATE.  STATE must be a valid TODO state string."
   (let ((condition (string-equal (org-entry-get nil "TODO") state)))
     (when (org-xor condition neg)
       (org-get-heading))))
 
 ;; Block if there are headings
 (defun org-edna-condition/headings? (neg)
+  "Condition to check if a target has headings in its file.
+
+Edna Syntax: headings?
+
+Block the source heading if any headings can be found in its
+file.  This means that target does not have to be a heading."
   (let ((condition (not (seq-empty-p (org-map-entries (lambda nil t))))))
     (when (org-xor condition neg)
       (buffer-name))))
 
 (defun org-edna-condition/variable-set? (neg var val)
+  "Condition to check if a variable is set in a target.
+
+Edna Syntax: variable-set?(VAR VAL)
+
+Evaluate VAR when visiting a target, and compare it with `equal'
+against VAL.  Block the source heading if VAR = VAL.
+
+Target does not have to be a heading."
   (let ((condition (equal (symbol-value var) val)))
     (when (org-xor condition neg)
       (format "%s %s= %s" var (if neg "!" "=") val))))
 
 (defun org-edna-condition/has-property? (neg prop val)
+  "Condition to check if a target heading has property PROP = VAL.
+
+Edna Syntax: has-property?(\"PROP\" \"VAL\")
+
+Block if the target heading has the property PROP set to VAL,
+both of which must be strings."
   (let ((condition (string-equal (org-entry-get nil prop) val)))
     (when (org-xor condition neg)
       (org-get-heading))))
 
 (defun org-edna-condition/re-search? (neg match)
+  "Condition to check for a regular expression in a target's file.
+
+Edna Syntax: re-search?(\"MATCH\")
+
+Block if regular expression MATCH can be found in target's file,
+starting from target's position."
   (let ((condition (re-search-forward match nil t)))
     (when (org-xor condition neg)
       (format "%s %s in %s" (if neg "Did Not Find" "Found") match 
(buffer-name)))))
@@ -741,6 +1008,15 @@ one is specified, the last will be used.
 
 
 (defun org-edna-handle-consideration (consideration blocks)
+  "Handle consideration CONSIDERATION.
+
+Edna Syntax: consideration(all) [1]
+Edna Syntax: consideration(N)   [2]
+Edna Syntax: consideration(P)   [3]
+
+Form 1: consider all targets when evaluating conditions.
+Form 2: consider the condition met if only N of the targets pass.
+Form 3: consider the condition met if only P% of the targets pass."
   (let ((first-block (seq-find #'identity blocks))
         (total-blocks (seq-length blocks)))
     (pcase consideration
@@ -814,9 +1090,9 @@ one is specified, the last will be used.
     map))
 
 (defun org-edna-edit ()
-  "Edit the blockers and triggers for current headline in a separate buffer."
+  "Edit the blockers and triggers for current heading in a separate buffer."
   (interactive)
-  ;; Move to the start of the current headline
+  ;; Move to the start of the current heading
   (let* ((heading-point (save-excursion
                           (org-back-to-heading)
                           (point-marker)))
diff --git a/org-edna.info b/org-edna.info
new file mode 100644
index 0000000..bf4d14b
--- /dev/null
+++ b/org-edna.info
@@ -0,0 +1,1233 @@
+This is org-edna.info, produced by makeinfo version 6.5 from
+org-edna.texi.
+
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Org Edna: (org-edna). Extensible Dependencies ’N’ Actions for Org Mode tasks.
+END-INFO-DIR-ENTRY
+
+
+File: org-edna.info,  Node: Top,  Next: Copying,  Up: (dir)
+
+Org Edna
+********
+
+* Menu:
+
+* Copying::
+* Introduction::                 A Brief Introduction to Edna
+* Basic Features::               Finders and Actions
+* Advanced Features::
+* Extending Edna::               What else can it do?
+* Contributing::                 I wanna help!
+
+— The Detailed Node Listing —
+
+Introduction
+
+* Installation and Setup::       How to install Edna
+* Basic Operation::              How to use Edna
+* Blockers::                     Blocking a TODO Item
+* Triggers::                     Triggering actions after completing a task
+* Syntax::                       Basic explanation of Edna’s syntax
+
+Basic Features
+
+* Finders::                      How to find targets
+* Actions::                      Next steps
+
+Finders
+
+* ancestors::                    Find a list of ancestors
+* chain-find::                   Find a target as org-depend does
+* children::                     Find all immediate children
+* descendants::                  Find all descendants
+* file::                         Find a file by name
+* first-child::                  Find the first child of a heading
+* ids::                          Find a list of headings with given IDs
+* match::                        Good old tag matching
+* next-sibling::                 Find the next sibling
+* next-sibling-wrap::            Find the next sibling, wrapping around
+* olp::                          Find a heading by its outline path
+* org-file::                     Find a file in org-directory
+* parent::                       Find a parent
+* previous-sibling::             Find the previous sibling
+* rest-of-siblings::             Find the remaining siblings
+* self::
+* siblings::                     Find all the siblings
+* siblings-wrap::                Find the siblings, but wrap around
+
+
+Actions
+
+* Scheduled/Deadline::           Operate on planning information
+* TODO State::                   Set todo state
+* Archive::                      Archive targets
+* Chain Property::               Copy properties from source to targets
+* Clocking::                     Clock in or out of a target
+* Property::                     Set properties of targets
+* Priority::                     Set priorities of targets
+* Tag::                          Tags of a target
+* Effort::                       So much effort!
+
+
+Advanced Features
+
+* Conditions::
+* Consideration::
+
+Conditions
+
+* done::
+* headings::
+* todo-state::
+* variable-set::
+* has-property::
+* re-search::                    Search for a regular expression
+* Negating Conditions::
+
+
+Extending Edna
+
+* Naming Conventions::           How to name new functions
+* Finders: Finders (1).          Making a new finder
+* Actions: Actions (1).          Making a new action
+* Conditions: Conditions (1).    Making a new condition
+
+Contributing
+
+* Bugs::
+* Development::
+
+
+
+File: org-edna.info,  Node: Copying,  Next: Introduction,  Prev: Top,  Up: Top
+
+Copying
+*******
+
+Copyright (C) 2017 Free Software Foundation, Inc.
+
+     This program is free software: you can redistribute it and/or
+     modify it under the terms of the GNU General Public License as
+     published by the Free Software Foundation, either version 3 of the
+     License, or (at your option) any later version.
+
+     This program is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with this program.  If not, see
+     <http://www.gnu.org/licenses/>.
+
+
+File: org-edna.info,  Node: Introduction,  Next: Basic Features,  Prev: 
Copying,  Up: Top
+
+Introduction
+************
+
+Extensible Dependencies ’N’ Actions (EDNA) for Org Mode tasks
+
+   Edna provides an extensible means of specifying conditions which must
+be fulfilled before a task can be completed and actions to take once it
+is.
+
+   Org Edna runs when either the BLOCKER or TRIGGER properties are set
+on a heading, and when it is changing from a TODO state to a DONE state.
+
+   For brevity, we use TODO state to indicate any state in
+‘org-not-done-keywords’, and DONE state to indicate any state in
+‘org-done-keywords’.
+
+* Menu:
+
+* Installation and Setup::       How to install Edna
+* Basic Operation::              How to use Edna
+* Blockers::                     Blocking a TODO Item
+* Triggers::                     Triggering actions after completing a task
+* Syntax::                       Basic explanation of Edna’s syntax
+
+
+File: org-edna.info,  Node: Installation and Setup,  Next: Basic Operation,  
Up: Introduction
+
+Installation and Setup
+======================
+
+*Requirements*
+
+Emacs   25.1
+seq     2.19
+org     9.0.5
+
+   There are two ways to install Edna: From GNU ELPA, or from source.
+
+   From ELPA:
+
+     M-x package-install org-edna
+
+   From Source:
+
+     bzr branch https://bzr.savannah.gnu.org/r/org-edna-el/ org-edna
+     make -C org-edna compile autoloads
+
+   After that, add the following to your init file (typically .emacs):
+
+     ;; Only necessary if installing from source
+     (add-to-list 'load-path "/full/path/to/org-edna/")
+     (load "/path/to/org-edna/org-edna-autoloads.el")
+
+     ;; Always necessary
+     (org-edna-load)
+
+   If you ever want to disable Edna, run ‘org-edna-unload’.
+
+
+File: org-edna.info,  Node: Basic Operation,  Next: Blockers,  Prev: 
Installation and Setup,  Up: Introduction
+
+Basic Operation
+===============
+
+Let’s start with an example: Say you want to do laundry, but once you’ve
+put your clothes in the washer, you forget about it.  Even with a tool
+like org-notify or appt, Org won’t know when to remind you.  If you’ve
+got them scheduled for an hour after the other, maybe you forgot one
+time, or ran a little late.  Now Org will remind you too early.
+
+   Edna can handle this for you like so:
+
+     * TODO Put clothes in washer
+       SCHEDULED: <2017-04-08 Sat 09:00>
+       :PROPERTIES:
+       :TRIGGER: next-sibling scheduled!("++1h")
+       :END:
+     * TODO Put clothes in dryer
+       :PROPERTIES:
+       :TRIGGER: next-sibling scheduled!("++1h")
+       :BLOCKER:  previous-sibling
+       :END:
+     * TODO Fold laundry
+       :PROPERTIES:
+       :TRIGGER: next-sibling scheduled!("++1h")
+       :BLOCKER:  previous-sibling
+       :END:
+     * TODO Put clothes away
+       :PROPERTIES:
+       :TRIGGER: next-sibling scheduled!("++1h")
+       :BLOCKER:  previous-sibling
+       :END:
+
+   After you’ve put your clothes in the washer and mark the task DONE,
+Edna will schedule the following task for one hour after you set the
+first heading as done.
+
+   Another example might be a checklist that you’ve done so many times
+that you do part of it on autopilot:
+
+     * TODO Address all TODOs in code
+     * TODO Commit Code to Repository
+
+   The last thing anyone wants is to find out that some part of the code
+on which they’ve been working for days has a surprise waiting for them.
+Once again, Edna can help:
+
+     * TODO Address all TODOs in code
+       :PROPERTIES:
+       :BLOCKER: file("main.cpp") file("code.cpp") re-search?("TODO")
+       :END:
+     * TODO Commit Code to Repository
+
+
+File: org-edna.info,  Node: Blockers,  Next: Triggers,  Prev: Basic Operation, 
 Up: Introduction
+
+Blockers
+========
+
+A blocker indicates conditions which must be met in order for a heading
+to be marked as DONE. Typically, this will be a list of headings that
+must be marked as DONE.
+
+
+File: org-edna.info,  Node: Triggers,  Next: Syntax,  Prev: Blockers,  Up: 
Introduction
+
+Triggers
+========
+
+A trigger is an action to take when a heading is set to done.  For
+example, scheduling another task, marking another task as TODO, or
+renaming a file.
+
+
+File: org-edna.info,  Node: Syntax,  Prev: Triggers,  Up: Introduction
+
+Syntax
+======
+
+Edna has its own language for commands, the basic form of which is
+KEYWORD(ARG1 ARG2 ...)
+
+   KEYWORD can be any valid lisp symbol, such as key-word, KEY_WORD!, or
+keyword?.
+
+   Each argument can be one of the following:
+
+   • A symbol, such as arg or org-mode
+   • A quoted string, such as “hello” or “My name is Edna”
+   • A number, such as 0.5, +1e3, or -5
+   • A UUID, such as c5e30c76-879a-494d-9281-3a4b559c1a3c
+
+   Each argument takes specific datatypes as input, so be sure to read
+the entry before using it.
+
+   The parentheses can be omitted for commands with no arguments.
+
+
+File: org-edna.info,  Node: Basic Features,  Next: Advanced Features,  Prev: 
Introduction,  Up: Top
+
+Basic Features
+**************
+
+The most basic features of Edna are *finders* and *actions*.
+
+* Menu:
+
+* Finders::                      How to find targets
+* Actions::                      Next steps
+
+
+File: org-edna.info,  Node: Finders,  Next: Actions,  Up: Basic Features
+
+Finders
+=======
+
+A finder specifies locations from which to test conditions or perform
+actions.  These locations are referred to as “targets”.  The current
+heading, i.e.  the one that is being blocked or triggered, is referred
+to as the “source” heading.
+
+   More than one finder may be used.  In this case, the targets are
+merged together, removing any duplicates.
+
+* Menu:
+
+* ancestors::                    Find a list of ancestors
+* chain-find::                   Find a target as org-depend does
+* children::                     Find all immediate children
+* descendants::                  Find all descendants
+* file::                         Find a file by name
+* first-child::                  Find the first child of a heading
+* ids::                          Find a list of headings with given IDs
+* match::                        Good old tag matching
+* next-sibling::                 Find the next sibling
+* next-sibling-wrap::            Find the next sibling, wrapping around
+* olp::                          Find a heading by its outline path
+* org-file::                     Find a file in org-directory
+* parent::                       Find a parent
+* previous-sibling::             Find the previous sibling
+* rest-of-siblings::             Find the remaining siblings
+* self::
+* siblings::                     Find all the siblings
+* siblings-wrap::                Find the siblings, but wrap around
+
+
+File: org-edna.info,  Node: ancestors,  Next: chain-find,  Up: Finders
+
+ancestors
+---------
+
+   • Syntax: ancestors
+
+   The ‘ancestors’ finder returns a list of the source heading’s
+ancestors.
+
+   For example:
+
+     * TODO Heading 1
+     ** TODO Heading 2
+     ** TODO Heading 3
+     *** TODO Heading 4
+     **** TODO Heading 5
+          :PROPERTIES:
+          :BLOCKER:  ancestors
+          :END:
+
+   In the above example, “Heading 5” will be blocked until “Heading 1”,
+“Heading 3”, and “Heading 4” are marked “DONE”, while “Heading 2” is
+ignored.
+
+
+File: org-edna.info,  Node: chain-find,  Next: children,  Prev: ancestors,  
Up: Finders
+
+chain-find
+----------
+
+   • Syntax: chain-find(OPTION OPTION...)
+
+   Identical to the chain argument in org-depend, chain-find selects its
+single target using the following method:
+
+  1. Creates a list of possible targets
+  2. Filters the targets from Step 1
+  3. Sorts the targets from Step 2
+
+   After this is finished, chain-find selects the first target in the
+list and returns it.
+
+   One option from each of the following three categories may be used;
+if more than one is specified, the last will be used.  Apart from that,
+argument order is irrelevant.
+
+   All arguments are symbols.
+
+   *Selection*
+
+   • from-top: Select siblings of the source heading, starting at the
+     top
+   • from-bottom: As above, but from the bottom
+   • from-current: Selects siblings, starting from the heading (wraps)
+   • no-wrap: As above, but without wrapping
+
+   *Filtering*
+
+   • todo-only: Select only targets with TODO state set that isn’t a
+     DONE keyword
+   • todo-and-done-only: Select all targets with a TODO state set
+
+   *Sorting*
+
+   • priority-up: Sort by priority, highest first
+   • priority-down: Same, but lowest first
+   • effort-up: Sort by effort, highest first
+   • effort-down: Sort by effort, lowest first
+
+
+File: org-edna.info,  Node: children,  Next: descendants,  Prev: chain-find,  
Up: Finders
+
+children
+--------
+
+   • Syntax: children
+
+   The ‘children’ finder returns a list of the *immediate* children of
+the source heading.  If the source has no children, no target is
+returned.
+
+   In order to get all levels of children of the source heading, use the
+*note descendants:: keyword instead.
+
+
+File: org-edna.info,  Node: descendants,  Next: file,  Prev: children,  Up: 
Finders
+
+descendants
+-----------
+
+   • Syntax: descendants
+
+   The ‘descendants’ finder returns a list of all descendants of the
+source heading.
+
+     * TODO Heading 1
+        :PROPERTIES:
+        :BLOCKER:  descendants
+        :END:
+     ** TODO Heading 2
+     *** TODO Heading 3
+     **** TODO Heading 4
+     ***** TODO Heading 5
+
+   In the above example, “Heading 1” will block until Headings 2, 3, 4,
+and 5 are DONE.
+
+
+File: org-edna.info,  Node: file,  Next: first-child,  Prev: descendants,  Up: 
Finders
+
+file
+----
+
+   • Syntax: file(“FILE”)
+
+   The ‘file’ finder finds a single file, specified as a string.  The
+returned target will be the minimum point in the file.
+
+   Note that this does not give a valid heading, so any conditions or
+actions that require will throw an error.  Consult the documentation for
+individual actions or conditions to determine which ones will and won’t
+work.
+
+   See *note conditions: Conditions. for how to set a different
+condition.  For example:
+
+     * TODO Test
+       :PROPERTIES:
+       :BLOCKER:  file("~/myfile.org") headings?
+       :END:
+
+   Here, “Test” will block until myfile.org is clear of headings.
+
+
+File: org-edna.info,  Node: first-child,  Next: ids,  Prev: file,  Up: Finders
+
+first-child
+-----------
+
+   • Syntax: first-child
+
+   Return the first child of the source heading.  If the source heading
+has no children, no target is returned.
+
+
+File: org-edna.info,  Node: ids,  Next: match,  Prev: first-child,  Up: Finders
+
+ids
+---
+
+   • Syntax: id(ID1 ID2 ...)
+
+   The ‘ids’ finder will search for headings with given IDs, using
+‘org-id’.  Any number of UUIDs may be specified.  For example:
+
+     * TODO Test
+       :PROPERTIES:
+       :BLOCKER:  ids(62209a9a-c63b-45ef-b8a8-12e47a9ceed9 
6dbd7921-a25c-4e20-b035-365677e00f30)
+       :END:
+
+   Here, “Test” will block until the heading with ID
+62209a9a-c63b-45ef-b8a8-12e47a9ceed9 and the heading with ID
+6dbd7921-a25c-4e20-b035-365677e00f30 are set to “DONE”.
+
+   Note that UUIDs need not be quoted; Edna will handle that for you.
+
+
+File: org-edna.info,  Node: match,  Next: next-sibling,  Prev: ids,  Up: 
Finders
+
+match
+-----
+
+   • Syntax: match(“MATCH-STRING” SCOPE SKIP)
+
+   The ‘match’ keyword will take any arguments that ‘org-map-entries’
+usually takes.  In fact, the arguments to ‘match’ are passed straight
+into ‘org-map-entries’.
+
+     * TODO Test
+       :PROPERTIES:
+       :BLOCKER:  match("test&mine" agenda)
+       :END:
+
+   “Test” will block until all entries tagged “test” and “mine” in the
+agenda files are marked DONE.
+
+   See the documentation for ‘org-map-entries’ for a full explanation of
+the first argument.
+
+
+File: org-edna.info,  Node: next-sibling,  Next: next-sibling-wrap,  Prev: 
match,  Up: Finders
+
+next-sibling
+------------
+
+   • Syntax: next-sibling
+
+   The ‘next-sibling’ keyword returns the next sibling of the source
+heading, if any.
+
+
+File: org-edna.info,  Node: next-sibling-wrap,  Next: olp,  Prev: 
next-sibling,  Up: Finders
+
+next-sibling-wrap
+-----------------
+
+   • Syntax: next-sibling-wrap
+
+   Find the next sibling of the source heading, if any.  If there isn’t,
+wrap back around to the first heading in the same subtree.
+
+
+File: org-edna.info,  Node: olp,  Next: org-file,  Prev: next-sibling-wrap,  
Up: Finders
+
+olp
+---
+
+   • Syntax: olp(“FILE” “OLP”)
+
+   Finds the heading given by OLP in FILE. Both arguments are strings.
+
+     * TODO Test
+       :PROPERTIES:
+       :BLOCKER:  olp("test.org" "path/to/heading")
+       :END:
+
+   “Test” will block if the heading “path/to/heading” in “test.org” is
+not DONE.
+
+
+File: org-edna.info,  Node: org-file,  Next: parent,  Prev: olp,  Up: Finders
+
+org-file
+--------
+
+   • Syntax: org-file(“FILE”)
+
+   A special form of ‘file’, ‘org-file’ will find FILE in
+‘org-directory’.
+
+   FILE is the relative path of a file in ‘org-directory’.  Nested files
+are allowed, such as “my-directory/my-file.org”.  The returned target is
+the minimum point of FILE.
+
+     * TODO Test
+       :PROPERTIES:
+       :BLOCKER:  org-file("test.org")
+       :END:
+
+   Note that the file still requires an extension; the “org” here just
+means to look in ‘org-directory’, not necessarily an Org mode file.
+
+
+File: org-edna.info,  Node: parent,  Next: previous-sibling,  Prev: org-file,  
Up: Finders
+
+parent
+------
+
+   • Syntax: parent
+
+   Returns the parent of the source heading, if any.
+
+
+File: org-edna.info,  Node: previous-sibling,  Next: rest-of-siblings,  Prev: 
parent,  Up: Finders
+
+previous-sibling
+----------------
+
+   • Syntax: previous-sibling
+
+   Returns the previous sibling of the source heading on the same level.
+
+
+File: org-edna.info,  Node: rest-of-siblings,  Next: self,  Prev: 
previous-sibling,  Up: Finders
+
+rest-of-siblings
+----------------
+
+   • Syntax: rest-of-siblings
+
+   Starting from the heading following the current one, all same-level
+siblings are returned.
+
+
+File: org-edna.info,  Node: self,  Next: siblings,  Prev: rest-of-siblings,  
Up: Finders
+
+self
+----
+
+   • Syntax: self
+
+   Returns the source heading.
+
+
+File: org-edna.info,  Node: siblings,  Next: siblings-wrap,  Prev: self,  Up: 
Finders
+
+siblings
+--------
+
+   • Syntax: siblings
+
+   Returns all siblings of the source heading as targets, starting from
+the first sibling, and ignoring the source heading.
+
+
+File: org-edna.info,  Node: siblings-wrap,  Prev: siblings,  Up: Finders
+
+siblings-wrap
+-------------
+
+   • Syntax: siblings-wrap
+
+   Finds the siblings on the same level as the source heading, wrapping
+when it reaches the end.
+
+
+File: org-edna.info,  Node: Actions,  Prev: Finders,  Up: Basic Features
+
+Actions
+=======
+
+Once Edna has collected its targets for a trigger, it will perform
+actions on them.
+
+   Actions must always end with ’!’.
+
+* Menu:
+
+* Scheduled/Deadline::           Operate on planning information
+* TODO State::                   Set todo state
+* Archive::                      Archive targets
+* Chain Property::               Copy properties from source to targets
+* Clocking::                     Clock in or out of a target
+* Property::                     Set properties of targets
+* Priority::                     Set priorities of targets
+* Tag::                          Tags of a target
+* Effort::                       So much effort!
+
+
+File: org-edna.info,  Node: Scheduled/Deadline,  Next: TODO State,  Up: Actions
+
+Scheduled/Deadline
+------------------
+
+   • Syntax: scheduled!(OPTIONS)
+   • Syntax: deadline!(OPTIONS)
+
+   Set the scheduled or deadline time of any target headings.
+
+   There are several forms that the planning keywords can take.  In the
+following, PLANNING is either scheduled or deadline.
+
+   • PLANNING!(“DATE[ TIME]”)
+
+     Sets PLANNING to DATE at TIME. If DATE is a weekday instead of a
+     date, then set PLANNING to the following weekday.  If TIME is not
+     specified, only a date will be added to the target.
+
+     Any string recognized by ‘org-read-date’ may be used for DATE.
+
+     TIME is a time string, such as HH:MM.
+
+   • PLANNING!(rm|remove)
+
+     Remove PLANNING from all targets.  The argument to this form may be
+     either a string or a symbol.
+
+   • PLANNING!(copy|cp)
+
+     Copy PLANNING info verbatim from the source heading to all targets.
+     The argument to this form may be either a string or a symbol.
+
+   • PLANNING!(“[+|-|++|–]NTHING”)
+
+     Increment(+) or decrement(-) target’s PLANNING by N THINGs relative
+     to either itself (+/-) or the current time (++/–).
+
+     N is an integer
+
+     THING is one of y (years), m (months), d (days), h (hours), or M
+     (minutes)
+
+   Examples:
+
+   scheduled!(“Mon 09:00”) -> Set SCHEDULED to the following Monday at
+9:00 deadline!(“++1h”) -> Set DEADLINE to one hour from now.
+deadline!(copy) deadline!(“+1h”) -> Copy the source deadline to the
+target, then increment it by an hour.
+
+
+File: org-edna.info,  Node: TODO State,  Next: Archive,  Prev: 
Scheduled/Deadline,  Up: Actions
+
+TODO State
+----------
+
+   • Syntax: todo!(NEW-STATE)
+
+   Sets the TODO state of the target heading to NEW-STATE.
+
+   NEW-STATE may either be a string or a symbol denoting the new TODO
+state.  It can also be the empty string, in which case the TODO state is
+removed.
+
+
+File: org-edna.info,  Node: Archive,  Next: Chain Property,  Prev: TODO State, 
 Up: Actions
+
+Archive
+-------
+
+   • Syntax: archive!
+
+   Archives all targets with confirmation.
+
+   Confirmation is controlled with ‘org-edna-prompt-for-archive’.  If
+this option is nil, Edna will not ask before archiving targets.
+
+
+File: org-edna.info,  Node: Chain Property,  Next: Clocking,  Prev: Archive,  
Up: Actions
+
+Chain Property
+--------------
+
+   • Syntax: chain!(“PROPERTY”)
+
+   Copies PROPERTY from the source entry to all targets.  Does nothing
+if the source heading has no property PROPERTY.
+
+
+File: org-edna.info,  Node: Clocking,  Next: Property,  Prev: Chain Property,  
Up: Actions
+
+Clocking
+--------
+
+   • Syntax: clock-in!
+   • Syntax: clock-out!
+
+   Clocks into or out of all targets.
+
+   ‘clock-in!’ has no special handling of targets, so be careful when
+specifying multiple targets.
+
+   In contrast, ‘clock-out!’ ignores its targets and only clocks out of
+the current clock, if any.
+
+
+File: org-edna.info,  Node: Property,  Next: Priority,  Prev: Clocking,  Up: 
Actions
+
+Property
+--------
+
+   • Syntax: set-property!(“PROPERTY” “VALUE”)
+
+   Sets the property PROPERTY on all targets to VALUE.
+
+   • Syntax: delete-property!(“PROPERTY”)
+
+   Deletes the property PROPERTY from all targets.
+
+
+File: org-edna.info,  Node: Priority,  Next: Tag,  Prev: Property,  Up: Actions
+
+Priority
+--------
+
+Sets the priority of all targets.
+
+   • Syntax: set-priority!(“PRIORITY”)
+
+     Set the priority to the first character of PRIORITY.
+
+   • Syntax: set-priority!(up)
+
+     Cycle the target’s priority up through the list of allowed
+     priorities.
+
+   • Syntax: set-priority!(down)
+
+     Cycle the target’s priority down through the list of allowed
+     priorities.
+
+   • Syntax: set-priority!(P)
+
+     Set the target’s priority to the character P.
+
+
+File: org-edna.info,  Node: Tag,  Next: Effort,  Prev: Priority,  Up: Actions
+
+Tag
+---
+
+   • Syntax: tag!(“TAG-SPEC”)
+
+   Tags all targets with TAG-SPEC, which is any valid tag specification,
+e.g.  tag1:tag2
+
+
+File: org-edna.info,  Node: Effort,  Prev: Tag,  Up: Actions
+
+Effort
+------
+
+   • Syntax: set-effort!(VALUE)
+
+   Sets the effort of all targets according to VALUE:
+
+   • If VALUE is a string, then the effort is set to VALUE
+   • If VALUE is an integer, then set the value to the VALUE’th allowed
+     effort property
+   • If VALUE is the symbol ’increment, increment effort
+
+
+File: org-edna.info,  Node: Advanced Features,  Next: Extending Edna,  Prev: 
Basic Features,  Up: Top
+
+Advanced Features
+*****************
+
+* Menu:
+
+* Conditions::
+* Consideration::
+
+
+File: org-edna.info,  Node: Conditions,  Next: Consideration,  Up: Advanced 
Features
+
+Conditions
+==========
+
+Edna gives you he option to specify *blocking conditions*.  Each
+condition is checked for each of the specified targets; if one of the
+conditions returns true for that target, then that heading is blocked.
+
+* Menu:
+
+* done::
+* headings::
+* todo-state::
+* variable-set::
+* has-property::
+* re-search::                    Search for a regular expression
+* Negating Conditions::
+
+
+File: org-edna.info,  Node: done,  Next: headings,  Up: Conditions
+
+done
+----
+
+   • Syntax: done?
+
+   Blocks the source heading if any target is DONE.
+
+
+File: org-edna.info,  Node: headings,  Next: todo-state,  Prev: done,  Up: 
Conditions
+
+headings
+--------
+
+   • Syntax: headings?
+
+   Blocks the source heading if any target belongs to a file that has an
+Org heading.
+
+     org-file("refile.org") headings?
+
+   The above example blocks if refile.org has any headings.
+
+
+File: org-edna.info,  Node: todo-state,  Next: variable-set,  Prev: headings,  
Up: Conditions
+
+todo-state
+----------
+
+   • Syntax: todo-state?(STATE)
+
+   Blocks if any target has a heading with TODO state set to STATE.
+
+   STATE may be a string or a symbol.
+
+
+File: org-edna.info,  Node: variable-set,  Next: has-property,  Prev: 
todo-state,  Up: Conditions
+
+variable-set
+------------
+
+   • Syntax: variable-set?(VARIABLE VALUE)
+
+   Blocks the source heading if VARIABLE is set to VALUE.
+
+   VARIABLE should be a symbol, and VALUE is any valid lisp expression
+
+     self variable-set?(test-variable,12)
+
+
+File: org-edna.info,  Node: has-property,  Next: re-search,  Prev: 
variable-set,  Up: Conditions
+
+has-property
+------------
+
+   • Syntax: has-property?(“PROPERTY” “VALUE”)
+
+   Tests each target for the property PROPERTY, and blocks if it’s set
+to VALUE.
+
+
+File: org-edna.info,  Node: re-search,  Next: Negating Conditions,  Prev: 
has-property,  Up: Conditions
+
+re-search
+---------
+
+   • Syntax: re-search?(“REGEXP”)
+
+   Blocks the source heading if the regular expression REGEXP is present
+in any of the targets.
+
+   The targets are expected to be files, although this will work with
+other targets as well.
+
+
+File: org-edna.info,  Node: Negating Conditions,  Prev: re-search,  Up: 
Conditions
+
+Negating Conditions
+-------------------
+
+Any condition can be negated using ’!’.
+
+     match("test") !has-property?("PROP","1")
+
+   The above example will cause the source heading to block if any
+heading tagged “test” does *not* have the property PROP set to “1”.
+
+
+File: org-edna.info,  Node: Consideration,  Prev: Conditions,  Up: Advanced 
Features
+
+Consideration
+=============
+
+Special keyword that’s only valid for blockers.
+
+   This keyword can allow specifying only a portion of tasks to
+consider:
+
+  1. consider(PERCENT)
+  2. consider(NUMBER)
+  3. consider(all) (Default)
+
+   (1) tells the blocker to only consider some portion of the targets.
+If at least PERCENT of them are in a DONE state, allow the task to be
+set to DONE. PERCENT must be a decimal.
+
+   (2) tells the blocker to only consider NUMBER of the targets.
+
+   (3) tells the blocker to consider all following targets.
+
+   A consideration must be specified before the targets to which it
+applies:
+
+     consider(0.5) siblings consider(all) match("find_me")
+
+   The above code will allow task completion if at least half the
+siblings are complete, and all tasks tagged “find_me” are complete.
+
+     consider(1) ids(ID1 ID2 ID3) consider(2) ids(ID3 ID4 ID5 ID6)
+
+   The above code will allow task completion if at least one of ID1,
+ID2, and ID3 are complete, and at least two of ID3, ID4, ID5, and ID6
+are complete.
+
+   If no consideration is given, ALL is assumed.
+
+
+File: org-edna.info,  Node: Extending Edna,  Next: Contributing,  Prev: 
Advanced Features,  Up: Top
+
+Extending Edna
+**************
+
+Extending Edna is (relatively) simple.
+
+   During operation, Edna searches for functions of the form
+org-edna-TYPE/KEYWORD.
+
+* Menu:
+
+* Naming Conventions::           How to name new functions
+* Finders: Finders (1).          Making a new finder
+* Actions: Actions (1).          Making a new action
+* Conditions: Conditions (1).    Making a new condition
+
+
+File: org-edna.info,  Node: Naming Conventions,  Next: Finders (1),  Up: 
Extending Edna
+
+Naming Conventions
+==================
+
+In order to distinguish between actions, finders, and conditions, we add
+’?’ to conditions and ’!’ to actions.  This is taken from the practice
+in Guile and Scheme to suffix destructive functions with ’!’ and
+predicates with ’?’.
+
+   Thus, one can have an action that files a target, and a finder that
+finds a file.
+
+
+File: org-edna.info,  Node: Finders (1),  Next: Actions (1),  Prev: Naming 
Conventions,  Up: Extending Edna
+
+Finders
+=======
+
+Finders have the form org-edna-finder/KEYWORD, like so:
+
+     (defun org-edna-finder/test-finder ()
+       (list (point-marker)))
+
+   All finders must return a list of markers, one for each target found,
+or nil if no targets were found.
+
+
+File: org-edna.info,  Node: Actions (1),  Next: Conditions (1),  Prev: Finders 
(1),  Up: Extending Edna
+
+Actions
+=======
+
+Actions have the form org-edna-action/KEYWORD!:
+
+     (defun org-edna-action/test-action! (last-entry arg1 arg2)
+       )
+
+   Each action has at least one argument: ‘last-entry’.  This is a
+marker for the current entry (not to be confused with the current
+target).
+
+   The rest of the arguments are the arguments specified in the form.
+
+
+File: org-edna.info,  Node: Conditions (1),  Prev: Actions (1),  Up: Extending 
Edna
+
+Conditions
+==========
+
+     (defun org-edna-condition/test-cond? (neg))
+
+   All conditions have at least one argument, “NEG”.  If NEG is non-nil,
+the condition should be negated.
+
+   Most conditions have the following form:
+
+     (defun org-edna-condition/test-condition? (neg)
+       (let ((condition (my-test-for-condition)))
+         (when (org-xor condition neg)
+           (string-for-blocking-entry-here))))
+
+   For conditions, we return true if condition is true and neg is false,
+or if condition is false and neg is true:
+
+cond   neg   res
+-------------------
+t      t     f
+t      f     t
+f      t     t
+f      f     f
+
+   This is an XOR table, so we pass CONDITION and NEG into ‘org-xor’ to
+get our result.
+
+   A condition must return a string if the current entry should be
+blocked.
+
+
+File: org-edna.info,  Node: Contributing,  Prev: Extending Edna,  Up: Top
+
+Contributing
+************
+
+We are all happy for any help you may provide.
+
+   First, check out the source code on Savannah:
+<https://savannah.nongnu.org/projects/org-edna-el/>
+
+     bzr branch https://bzr.savannah.gnu.org/r/org-edna-el/ org-edna
+
+   You’ll also want a copy of the most recent Org Mode source:
+
+     git clone git://orgmode.org/org-mode.git
+
+* Menu:
+
+* Bugs::
+* Development::
+
+
+File: org-edna.info,  Node: Bugs,  Next: Development,  Up: Contributing
+
+Bugs
+====
+
+There are two ways to submit bug reports:
+
+  1. Using the bug tracker at Savannah
+  2. Sending an email using ‘org-edna-submit-bug-report’
+
+   When submitting a bug report, be sure to include the Edna form that
+caused the bug, with as much context as possible.
+
+
+File: org-edna.info,  Node: Development,  Prev: Bugs,  Up: Contributing
+
+Development
+===========
+
+If you’re new to bazaar, we recommend using Emacs’s built-in VC package.
+It eases the overhead of dealing with a brand new VCS with a few
+standard commands.  For more information, see the info page on it (In
+Emacs, this is C-h r m Introduction to VC RET).
+
+   To contribute with bazaar, you can do the following:
+
+     # Hack away and make your changes
+     $ bzr commit -m "Changes I've made"
+     $ bzr send -o file-name.txt
+
+   Then, use ‘org-edna-submit-bug-report’ and attach “file-name.txt”.
+We can then merge that into the main development branch.
+
+   There are a few rules to follow:
+
+   • Verify that any new Edna keywords follow the appropriate naming
+     conventions
+   • Any new keywords should be documented
+   • We operate on headings, not headlines
+        • Use one word to avoid confusion
+   • Run ’make check’ to verify that your mods don’t break anything
+   • Avoid additional or altered dependencies if at all possible
+        • Exception: New versions of Org mode are allowed
+
+
+
+Tag Table:
+Node: Top225
+Node: Copying3115
+Node: Introduction3932
+Node: Installation and Setup4880
+Node: Basic Operation5673
+Node: Blockers7524
+Node: Triggers7810
+Node: Syntax8072
+Node: Basic Features8762
+Node: Finders9065
+Node: ancestors10568
+Node: chain-find11152
+Node: children12490
+Node: descendants12889
+Node: file13399
+Node: first-child14148
+Node: ids14396
+Node: match15057
+Node: next-sibling15695
+Node: next-sibling-wrap15940
+Node: olp16242
+Node: org-file16654
+Node: parent17299
+Node: previous-sibling17485
+Node: rest-of-siblings17729
+Node: self17992
+Node: siblings18148
+Node: siblings-wrap18406
+Node: Actions18639
+Node: Scheduled/Deadline19381
+Node: TODO State20971
+Node: Archive21339
+Node: Chain Property21659
+Node: Clocking21942
+Node: Property22354
+Node: Priority22676
+Node: Tag23245
+Node: Effort23462
+Node: Advanced Features23851
+Node: Conditions24036
+Node: done24524
+Node: headings24680
+Node: todo-state25001
+Node: variable-set25264
+Node: has-property25612
+Node: re-search25881
+Node: Negating Conditions26241
+Node: Consideration26604
+Node: Extending Edna27780
+Node: Naming Conventions28270
+Node: Finders (1)28733
+Node: Actions (1)29099
+Node: Conditions (1)29564
+Node: Contributing30454
+Node: Bugs30926
+Node: Development31278
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/org-edna.org b/org-edna.org
index 240acae..17b394f 100644
--- a/org-edna.org
+++ b/org-edna.org
@@ -10,7 +10,7 @@
 #+OPTIONS: *:t <:t d:nil todo:nil pri:nil tags:not-in-toc
 
 #+TEXINFO_DIR_CATEGORY: Emacs
-#+TEXINFO_DIR_TITLE: Org Edna: (edna)
+#+TEXINFO_DIR_TITLE: Org Edna: (org-edna)
 #+TEXINFO_DIR_DESC: Extensible Dependencies 'N' Actions for Org Mode tasks
 
 * Copying
@@ -42,7 +42,7 @@ Edna provides an extensible means of specifying conditions 
which must be
 fulfilled before a task can be completed and actions to take once it is.
 
 Org Edna runs when either the BLOCKER or TRIGGER properties are set on a
-headline, and when it is changing from a TODO state to a DONE state.
+heading, and when it is changing from a TODO state to a DONE state.
 
 For brevity, we use TODO state to indicate any state in 
~org-not-done-keywords~,
 and DONE state to indicate any state in ~org-done-keywords~.
@@ -124,7 +124,7 @@ Edna can handle this for you like so:
 #+END_SRC
 
 After you've put your clothes in the washer and mark the task DONE, Edna will
-schedule the following task for one hour after you set the first headline as
+schedule the following task for one hour after you set the first heading as
 done.
 
 Another example might be a checklist that you've done so many times that you do
@@ -153,8 +153,8 @@ can help:
 :DESCRIPTION: Blocking a TODO Item
 :END:
 
-A blocker indicates conditions which must be met in order for a headline to be
-marked as DONE.  Typically, this will be a list of headlines that must be 
marked
+A blocker indicates conditions which must be met in order for a heading to be
+marked as DONE.  Typically, this will be a list of headings that must be marked
 as DONE.
 
 ** Triggers
@@ -163,7 +163,7 @@ as DONE.
 :DESCRIPTION: Triggering actions after completing a task
 :END:
 
-A trigger is an action to take when a headline is set to done.  For example,
+A trigger is an action to take when a heading is set to done.  For example,
 scheduling another task, marking another task as TODO, or renaming a file.
 
 ** Syntax
@@ -202,7 +202,8 @@ The most basic features of Edna are *finders* and *actions*.
 :CUSTOM_ID: finders
 :END:
 A finder specifies locations from which to test conditions or perform actions.
-These locations are referred to as "targets".
+These locations are referred to as "targets".  The current heading, i.e. the 
one
+that is being blocked or triggered, is referred to as the "source" heading.
 
 More than one finder may be used.  In this case, the targets are merged
 together, removing any duplicates.
@@ -213,9 +214,9 @@ together, removing any duplicates.
 :CUSTOM_ID: ancestors
 :END:
 
-Syntax: ancestors
+- Syntax: ancestors
 
-The ~ancestors~ finder returns a list of the current headline's ancestors.
+The ~ancestors~ finder returns a list of the source heading's ancestors.
 
 For example:
 
@@ -239,7 +240,7 @@ In the above example, "Heading 5" will be blocked until 
"Heading 1", "Heading
 :DESCRIPTION: Find a target as org-depend does
 :END:
 
-Syntax: chain-find(OPTION OPTION...)
+- Syntax: chain-find(OPTION OPTION...)
 
 Identical to the chain argument in org-depend, chain-find selects its single
 target using the following method:
@@ -252,13 +253,16 @@ After this is finished, chain-find selects the first 
target in the list and
 returns it.
 
 One option from each of the following three categories may be used; if more 
than
-one is specified, the last will be used.
+one is specified, the last will be used.  Apart from that, argument order is
+irrelevant.
+
+All arguments are symbols.
 
 *Selection*
 
-- from-top:     Select siblings of the current headline, starting at the top
+- from-top:     Select siblings of the source heading, starting at the top
 - from-bottom:  As above, but from the bottom
-- from-current: Selects siblings, starting from the headline (wraps)
+- from-current: Selects siblings, starting from the heading (wraps)
 - no-wrap:      As above, but without wrapping
 
 *Filtering*
@@ -279,12 +283,12 @@ one is specified, the last will be used.
 :DESCRIPTION: Find all immediate children
 :END:
 
-Syntax: children
+- Syntax: children
 
-The ~children~ finder returns a list of the *immediate* children of the current
-headline.
+The ~children~ finder returns a list of the *immediate* children of the source
+heading.  If the source has no children, no target is returned.
 
-In order to get all levels of children of the current headline, use the
+In order to get all levels of children of the source heading, use the
 [[#descendants][descendants]] keyword instead.
 
 *** descendants
@@ -293,10 +297,9 @@ In order to get all levels of children of the current 
headline, use the
 :DESCRIPTION: Find all descendants
 :END:
 
-Syntax: descendants
+- Syntax: descendants
 
-The ~descendants~ finder returns a list of all descendants of the current
-headline.
+The ~descendants~ finder returns a list of all descendants of the source 
heading.
 
 #+BEGIN_SRC org
 ,* TODO Heading 1
@@ -323,8 +326,12 @@ DONE.
 The ~file~ finder finds a single file, specified as a string.  The returned 
target
 will be the minimum point in the file.
 
-Note that with the default condition, ~file~ won't work.  See 
[[#conditions][conditions]] for how
-to set a different condition.  For example:
+Note that this does not give a valid heading, so any conditions
+or actions that require will throw an error.  Consult the
+documentation for individual actions or conditions to determine
+which ones will and won't work.
+
+See [[#conditions][conditions]] for how to set a different condition.  For 
example:
 
 #+BEGIN_SRC org
 ,* TODO Test
@@ -333,27 +340,28 @@ to set a different condition.  For example:
   :END:
 #+END_SRC
 
-Here, "Test" will block until myfile.org is clear of headlines.
+Here, "Test" will block until myfile.org is clear of headings.
 
 *** first-child
 :PROPERTIES:
 :CUSTOM_ID: first-child
-:DESCRIPTION: Find the first child of a headline
+:DESCRIPTION: Find the first child of a heading
 :END:
 
 - Syntax: first-child
 
-The ~first-child~ finder returns the first child of a headline, if any.
+Return the first child of the source heading.  If the source heading has no
+children, no target is returned.
 
 *** ids
 :PROPERTIES:
-:DESCRIPTION: Find a list of headlines with given IDs
+:DESCRIPTION: Find a list of headings with given IDs
 :CUSTOM_ID: ids
 :END:
 
 - Syntax: id(ID1 ID2 ...)
 
-The ~ids~ finder will search for headlines with given IDs, using ~org-id~.  Any
+The ~ids~ finder will search for headings with given IDs, using ~org-id~.  Any
 number of UUIDs may be specified.  For example:
 
 #+BEGIN_SRC org
@@ -363,8 +371,8 @@ number of UUIDs may be specified.  For example:
   :END:
 #+END_SRC
 
-Here, "Test" will block until the headline with ID
-62209a9a-c63b-45ef-b8a8-12e47a9ceed9 and the headline with ID
+Here, "Test" will block until the heading with ID
+62209a9a-c63b-45ef-b8a8-12e47a9ceed9 and the heading with ID
 6dbd7921-a25c-4e20-b035-365677e00f30 are set to "DONE".
 
 Note that UUIDs need not be quoted; Edna will handle that for you.
@@ -401,8 +409,7 @@ argument.
 
 - Syntax: next-sibling
 
-The ~next-sibling~ keyword returns the next sibling of the current heading, if
-any.
+The ~next-sibling~ keyword returns the next sibling of the source heading, if 
any.
 
 *** next-sibling-wrap
 :PROPERTIES:
@@ -412,13 +419,13 @@ any.
 
 - Syntax: next-sibling-wrap
 
-Find the next sibling of the current heading, if any.  If there isn't, wrap 
back
+Find the next sibling of the source heading, if any.  If there isn't, wrap back
 around to the first heading in the same subtree.
 
 *** olp
 :PROPERTIES:
 :CUSTOM_ID: olp
-:DESCRIPTION: Find a headline by its outline path
+:DESCRIPTION: Find a heading by its outline path
 :END:
 
 - Syntax: olp("FILE" "OLP")
@@ -444,6 +451,10 @@ Finds the heading given by OLP in FILE.  Both arguments 
are strings.
 
 A special form of ~file~, ~org-file~ will find FILE in ~org-directory~.
 
+FILE is the relative path of a file in ~org-directory~.  Nested
+files are allowed, such as "my-directory/my-file.org".  The
+returned target is the minimum point of FILE.
+
 #+BEGIN_SRC org
 ,* TODO Test
   :PROPERTIES:
@@ -451,7 +462,9 @@ A special form of ~file~, ~org-file~ will find FILE in 
~org-directory~.
   :END:
 #+END_SRC
 
-Note that the file still requires an extension.
+Note that the file still requires an extension; the "org" here
+just means to look in ~org-directory~, not necessarily an
+Org mode file.
 
 *** parent
 :PROPERTIES:
@@ -461,7 +474,7 @@ Note that the file still requires an extension.
 
 - Syntax: parent
 
-Returns the parent of the current headline, if any.
+Returns the parent of the source heading, if any.
 
 *** previous-sibling
 :PROPERTIES:
@@ -471,7 +484,7 @@ Returns the parent of the current headline, if any.
 
 - Syntax: previous-sibling
 
-Returns the previous sibling of the current headline on the same level.
+Returns the previous sibling of the source heading on the same level.
 
 *** rest-of-siblings
 :PROPERTIES:
@@ -481,7 +494,7 @@ Returns the previous sibling of the current headline on the 
same level.
 
 - Syntax: rest-of-siblings
 
-Starting from the headline following the current one, all same-level siblings
+Starting from the heading following the current one, all same-level siblings
 are returned.
 
 *** self
@@ -491,7 +504,7 @@ are returned.
 
 - Syntax: self
 
-Returns the current headline.
+Returns the source heading.
 
 *** siblings
 :PROPERTIES:
@@ -501,7 +514,8 @@ Returns the current headline.
 
 - Syntax: siblings
 
-Returns all siblings of the source heading as targets.
+Returns all siblings of the source heading as targets, starting from the first
+sibling, and ignoring the source heading.
 
 *** siblings-wrap
 :PROPERTIES:
@@ -511,7 +525,7 @@ Returns all siblings of the source heading as targets.
 
 - Syntax: siblings-wrap
 
-Finds the siblings on the same level as the current headline, wrapping when it
+Finds the siblings on the same level as the source heading, wrapping when it
 reaches the end.
 
 ** Actions
@@ -526,36 +540,41 @@ Actions must always end with '!'.
 *** Scheduled/Deadline
 :PROPERTIES:
 :CUSTOM_ID: planning
+:DESCRIPTION: Operate on planning information
 :END:
 
 - Syntax: scheduled!(OPTIONS)
 - Syntax: deadline!(OPTIONS)
 
-There are several forms that the planning keywords can take:
+Set the scheduled or deadline time of any target headings.
+
+There are several forms that the planning keywords can take.  In the following,
+PLANNING is either scheduled or deadline.
 
-- PLANNING("WKDY[ TIME]")
+- PLANNING!("DATE[ TIME]")
 
-  Sets PLANNING to the following weekday WKDY at TIME.  If TIME is not
-  specified, only a date will be added to the target.
+  Sets PLANNING to DATE at TIME.  If DATE is a weekday instead of a date, then
+  set PLANNING to the following weekday.  If TIME is not specified, only a date
+  will be added to the target.
 
-  WKDY is a weekday or weekday abbreviation (see ~org-read-date~)
+  Any string recognized by ~org-read-date~ may be used for DATE.
 
-  TIME is a time string HH:MM, etc.
+  TIME is a time string, such as HH:MM.
 
-- PLANNING(rm|remove)
+- PLANNING!(rm|remove)
 
   Remove PLANNING from all targets.  The argument to this form may be either a
   string or a symbol.
 
-- PLANNING(copy|cp)
+- PLANNING!(copy|cp)
 
-  Copy PLANNING info verbatim from the current headline to all targets.  The
+  Copy PLANNING info verbatim from the source heading to all targets.  The
   argument to this form may be either a string or a symbol.
 
-- PLANNING("[+|-][+|-]NTHING")
+- PLANNING!("[+|-|++|--]NTHING")
 
-  Increment(+) or decrement(-) source (double) or current (single) PLANNING by 
N
-  THINGs
+  Increment(+) or decrement(-) target's PLANNING by N THINGs relative to either
+  itself (+/-) or the current time (++/--).
 
   N is an integer
 
@@ -564,17 +583,25 @@ There are several forms that the planning keywords can 
take:
 Examples:
 
 scheduled!("Mon 09:00") -> Set SCHEDULED to the following Monday at 9:00
+deadline!("++1h") -> Set DEADLINE to one hour from now.
+deadline!(copy) deadline!("+1h") -> Copy the source deadline to the target, 
then increment it by an hour.
 *** TODO State
+:PROPERTIES:
+:CUSTOM_ID: todo!
+:DESCRIPTION: Set todo state
+:END:
 
 - Syntax: todo!(NEW-STATE)
 
-Sets the TODO state of the target headline to NEW-STATE.
+Sets the TODO state of the target heading to NEW-STATE.
 
-NEW-STATE may either be a string or a symbol denoting the new TODO state.
+NEW-STATE may either be a string or a symbol denoting the new TODO state.  It
+can also be the empty string, in which case the TODO state is removed.
 
 *** Archive
 :PROPERTIES:
 :CUSTOM_ID: archive!
+:DESCRIPTION: Archive targets
 :END:
 
 - Syntax: archive!
@@ -582,15 +609,24 @@ NEW-STATE may either be a string or a symbol denoting the 
new TODO state.
 Archives all targets with confirmation.
 
 Confirmation is controlled with ~org-edna-prompt-for-archive~.  If this option 
is
-nil, Edna will not ask before archiving the target.
+nil, Edna will not ask before archiving targets.
 
 *** Chain Property
+:PROPERTIES:
+:CUSTOM_ID: chain!
+:DESCRIPTION: Copy properties from source to targets
+:END:
 
 - Syntax: chain!("PROPERTY")
 
-Copies PROPERTY from the source entry to all targets.
+Copies PROPERTY from the source entry to all targets.  Does nothing if the
+source heading has no property PROPERTY.
 
 *** Clocking
+:PROPERTIES:
+:CUSTOM_ID: clocking
+:DESCRIPTION: Clock in or out of a target
+:END:
 
 - Syntax: clock-in!
 - Syntax: clock-out!
@@ -600,9 +636,15 @@ Clocks into or out of all targets.
 ~clock-in!~ has no special handling of targets, so be careful when specifying
 multiple targets.
 
+In contrast, ~clock-out!~ ignores its targets and only clocks out of the 
current
+clock, if any.
 *** Property
+:PROPERTIES:
+:CUSTOM_ID: properties
+:DESCRIPTION: Set properties of targets
+:END:
 
-- Syntax: set-property!("PROPERTY","VALUE")
+- Syntax: set-property!("PROPERTY" "VALUE")
 
 Sets the property PROPERTY on all targets to VALUE.
 
@@ -611,15 +653,34 @@ Sets the property PROPERTY on all targets to VALUE.
 Deletes the property PROPERTY from all targets.
 
 *** Priority
+:PROPERTIES:
+:CUSTOM_ID: priorities
+:DESCRIPTION: Set priorities of targets
+:END:
 
-- Syntax: set-priority!(PRIORITY)
+Sets the priority of all targets.
 
-Sets the priority of all targets to PRIORITY.  PRIORITY is processed as 
follows:
+- Syntax: set-priority!("PRIORITY")
 
-- If PRIORITY is a string, the first character is used as the priority
-- Any other value is passed into ~org-priority~ verbatim, so it can be 'up, 
'down, or an integer
+  Set the priority to the first character of PRIORITY.
+
+- Syntax: set-priority!(up)
+
+  Cycle the target's priority up through the list of allowed priorities.
+
+- Syntax: set-priority!(down)
+
+  Cycle the target's priority down through the list of allowed priorities.
+
+- Syntax: set-priority!(P)
+
+  Set the target's priority to the character P.
 
 *** Tag
+:PROPERTIES:
+:CUSTOM_ID: tags
+:DESCRIPTION: Tags of a target
+:END:
 
 - Syntax: tag!("TAG-SPEC")
 
@@ -627,6 +688,10 @@ Tags all targets with TAG-SPEC, which is any valid tag 
specification,
 e.g. tag1:tag2
 
 *** Effort
+:PROPERTIES:
+:CUSTOM_ID: effort
+:DESCRIPTION: So much effort!
+:END:
 
 - Syntax: set-effort!(VALUE)
 
@@ -647,7 +712,10 @@ Sets the effort of all targets according to VALUE:
 
 Edna gives you he option to specify *blocking conditions*.  Each condition is 
checked
 for each of the specified targets; if one of the conditions returns true for
-that target, then that headline is blocked.
+that target, then the source heading is blocked.
+
+If no condition is specified, ~!done?~ is used by default, which means block if
+any target heading isn't done.
 
 *** done
 :PROPERTIES:
@@ -656,7 +724,7 @@ that target, then that headline is blocked.
 
 - Syntax: done?
 
-Blocks the current headline if any target is DONE.
+Blocks the source heading if any target heading is DONE.
 
 *** headings
 :PROPERTIES:
@@ -665,7 +733,8 @@ Blocks the current headline if any target is DONE.
 
 - Syntax: headings?
 
-Blocks the current headline if any target belongs to a file that has an Org 
heading.
+Blocks the source heading if any target belongs to a file that has an Org
+heading.  This means that target does not have to be a heading.
 
 #+BEGIN_EXAMPLE
 org-file("refile.org") headings?
@@ -680,7 +749,7 @@ The above example blocks if refile.org has any headings.
 
 - Syntax: todo-state?(STATE)
 
-Blocks if any target has a headline with TODO state set to STATE.
+Blocks if any target heading has TODO state set to STATE.
 
 STATE may be a string or a symbol.
 
@@ -689,14 +758,15 @@ STATE may be a string or a symbol.
 :CUSTOM_ID: variable-set
 :END:
 
-- Syntax: variable-set?(VARIABLE,VALUE)
+- Syntax: variable-set?(VARIABLE VALUE)
 
-Blocks the current headline if VARIABLE is set to VALUE.
+Evaluate VARIABLE when visiting a target, and compare it with ~equal~
+against VALUE.  Block the source heading if VARIABLE = VALUE.
 
-VARIABLE should be a symbol, and VALUE is any valid lisp expression
+VARIABLE should be a symbol, and VALUE is any valid lisp expression.
 
 #+BEGIN_EXAMPLE
-self variable-set?(test-variable,12)
+self variable-set?(test-variable 12)
 #+END_EXAMPLE
 
 *** has-property
@@ -704,7 +774,7 @@ self variable-set?(test-variable,12)
 :CUSTOM_ID: has-property
 :END:
 
-- Syntax: has-property?("PROPERTY","VALUE")
+- Syntax: has-property?("PROPERTY" "VALUE")
 
 Tests each target for the property PROPERTY, and blocks if it's set to VALUE.
 
@@ -716,7 +786,7 @@ Tests each target for the property PROPERTY, and blocks if 
it's set to VALUE.
 
 - Syntax: re-search?("REGEXP")
 
-Blocks the current headline if the regular expression REGEXP is present in any
+Blocks the source heading if the regular expression REGEXP is present in any
 of the targets.
 
 The targets are expected to be files, although this will work with other 
targets
@@ -726,13 +796,13 @@ as well.
 :PROPERTIES:
 :CUSTOM_ID: negate
 :END:
-Any condition can be negated using '!'.
+Any condition can be negated by using '!' before the condition.
 
 #+BEGIN_EXAMPLE
-match("test") !has-property?("PROP","1")
+match("test") !has-property?("PROP" "1")
 #+END_EXAMPLE
 
-The above example will cause the current headline to block if any headline
+The above example will cause the source heading to block if any heading
 tagged "test" does *not* have the property PROP set to "1".
 ** Consideration
 Special keyword that's only valid for blockers.
@@ -875,7 +945,7 @@ You'll also want a copy of the most recent Org Mode source:
 git clone git://orgmode.org/org-mode.git
 #+END_SRC
 
-*Bugs*
+** Bugs
 
 There are two ways to submit bug reports:
 
@@ -885,14 +955,30 @@ There are two ways to submit bug reports:
 When submitting a bug report, be sure to include the Edna form that caused the
 bug, with as much context as possible.
 
-*Development*
+** Development
+
+If you're new to bazaar, we recommend using Emacs's built-in VC package.  It
+eases the overhead of dealing with a brand new VCS with a few standard 
commands.
+For more information, see the info page on it (In Emacs, this is
+C-h r m Introduction to VC RET).
+
+To contribute with bazaar, you can do the following:
+
+#+begin_src shell
+# Hack away and make your changes
+$ bzr commit -m "Changes I've made"
+$ bzr send -o file-name.txt
+#+end_src
 
-Submitting patches along with a bug report is the easiest way.
+Then, use ~org-edna-submit-bug-report~ and attach "file-name.txt".  We can then
+merge that into the main development branch.
 
 There are a few rules to follow:
 
 - Verify that any new Edna keywords follow the appropriate naming conventions
 - Any new keywords should be documented
+- We operate on headings, not headlines
+  - Use one word to avoid confusion
 - Run 'make check' to verify that your mods don't break anything
 - Avoid additional or altered dependencies if at all possible
   - Exception: New versions of Org mode are allowed



reply via email to

[Prev in Thread] Current Thread [Next in Thread]