Browse Source

Allow optional argument to {{{property}}} for remote entries

* lisp/org-macro.el (org-macro-initialize-templates): "property"
  template accepts an optional argument, as a search option to grab
  properties from other headlines.

* doc/org.texi (Macro replacement): Document new feature.  Improve
  documentation.
(An example): Update documentation.

* testing/lisp/test-org-macro.el (test-org/macro-replace-all): Add
  tests.
Nicolas Goaziou 9 years ago
parent
commit
fa5f8c8f90
3 changed files with 86 additions and 21 deletions
  1. 41 19
      doc/org.texi
  2. 11 1
      lisp/org-macro.el
  3. 34 1
      testing/lisp/test-org-macro.el

+ 41 - 19
doc/org.texi

@@ -10174,7 +10174,6 @@ an index} for more information.
 
 
 
-
 @node Macro replacement
 @section Macro replacement
 @cindex macro replacement, during export
@@ -10194,23 +10193,46 @@ escaped with another backslash character.}.
 
 These references, called macros, can be inserted anywhere Org markup is
 recognized: paragraphs, headlines, verse blocks, tables cells and lists.
-They cannot be used within ordinary keywords (starting with @code{#+}) but
-are allowed in @code{#+CAPTION}, @code{#+TITLE}, @code{#+AUTHOR} and
-@code{#+EMAIL}.
+They can also be used in keywords accepting Org syntax, e.g.,
+@code{#+CAPTION}, @code{#+TITLE}, @code{#+AUTHOR}, @code{#+DATE} and some
+others, export back-end specific, ones.
 
 In addition to user-defined macros, a set of predefined macros can be used:
-@code{@{@{@{title@}@}@}}, @code{@{@{@{author@}@}@}}, and
-@code{@{@{@{email@}@}@}} are replaced with the information set by their
-respective keywords.  Further, @code{@{@{@{date(@var{FORMAT})@}@}@}},
-@code{@{@{@{time(@var{FORMAT})@}@}@}} and
-@code{@{@{@{modification-time(@var{FORMAT})@}@}@}} refer to the @code{#+DATE}
-keyword, the current date, and the modification time of the file being
-exported, respectively.  @var{FORMAT} should be a format string understood by
-@code{format-time-string}.  Note that @var{FORMAT} is an optional argument to
-the @code{@{@{@{date@}@}@}} macro, and that it will only be used if
-@code{#+DATE} is a single timestamp.  Finally, the filename is available via
-@code{@{@{@{input-file@}@}@}} and properties can be accessed using
-@code{@{@{@{property(@var{PROPERTY-NAME})@}@}@}}.
+
+@table @code
+@item @{@{@{title@}@}@}
+@itemx @{@{@{author@}@}@}
+@itemx @{@{@{email@}@}@}
+@cindex title, macro
+@cindex author, macro
+@cindex email, macro
+These macros are replaced with the information available at the time of
+export.
+
+@item @{@{@{date@}@}@}
+@itemx @{@{@{date(@var{FORMAT})@}@}@}
+@itemx @{@{@{time(@var{FORMAT})@}@}@}
+@itemx @{@{@{modification-time(@var{FORMAT})@}@}@}
+@cindex date, macro
+@cindex time, macro
+@cindex modification time, macro
+These macros refer to the @code{#+DATE} keyword, the current date, and the
+modification time of the file being exported, respectively.  @samp{FORMAT}
+should be a format string understood by @code{format-time-string}.  Note that
+@var{FORMAT} is an optional argument to the @code{@{@{@{date@}@}@}} macro,
+and that it will only be used if @code{#+DATE} is a single timestamp.
+
+@item @{@{@{input-file@}@}@}
+@cindex input file, macro
+This macro refers to the filename of the exported file, if any.
+
+@item @{@{@{property(@var{PROPERTY-NAME})@}@}@}
+@itemx @{@{@{property(@var{PROPERTY-NAME},@var{SEARCH-OPTION})@}@}@}
+@cindex property, macro
+This macro returns the value of property @var{PROPERTY-NAME} in current
+entry.  If @var{SEARCH-OPTION} (@pxref(Search options}) refers to a remote
+entry, it will be used instead.
+@end table
 
 The surrounding brackets can be made invisible by setting
 @code{org-hide-macro-markers} non-@code{nil}.
@@ -13637,7 +13659,7 @@ length, using @code{:columns} attribute.
 Here is a thorough example.  @inforef{GNU Sample Texts,,texinfo} for an
 equivalent Texinfo code.
 
-@smallexample
+@example
 #+MACRO: version 2.0
 #+MACRO: updated last updated 4 March 2014
 
@@ -13655,7 +13677,7 @@ equivalent Texinfo code.
 #+TEXINFO_DIR_DESC: Invoking sample
 
 #+TEXINFO_PRINTED_TITLE: GNU Sample
-#+SUBTITLE: for version 2.0, last updated 4 March 2014
+#+SUBTITLE: for version @{@{@{version@}@}@}, @{@{@{updated@}@}@}
 
 * Copying 
   :PROPERTIES:
@@ -13697,7 +13719,7 @@ equivalent Texinfo code.
   :PROPERTIES:
   :INDEX:    cp
   :END:
-@end smallexample
+@end example
 
 @node iCalendar export
 @section iCalendar export

+ 11 - 1
lisp/org-macro.el

@@ -123,7 +123,17 @@ function installs the following ones: \"property\",
 		(push cell templates))))))
     ;; Install hard-coded macros.
     (mapc update-templates
-	  (list (cons "property" "(eval (org-entry-get nil \"$1\" 'selective))")
+	  (list (cons "property"
+		      "(eval (save-excursion
+        (let ((l \"$2\"))
+          (when (org-string-nw-p l)
+            (condition-case _
+                (let ((org-link-search-must-match-exact-headline t))
+                  (org-link-search l nil nil t))
+              (error
+               (error \"Macro property failed: cannot find location %s\"
+                      l)))))
+        (org-entry-get nil \"$1\" 'selective)))")
 		(cons "time" "(eval (format-time-string \"$1\"))")))
     (let ((visited-file (buffer-file-name (buffer-base-buffer))))
       (when (and visited-file (file-exists-p visited-file))

+ 34 - 1
testing/lisp/test-org-macro.el

@@ -74,7 +74,40 @@
 		org-test-dir)
       (org-macro-initialize-templates)
       (org-macro-replace-all org-macro-templates)
-      (buffer-string)))))
+      (buffer-string))))
+  ;; Test special "property" macro.  With only one argument, retrieve
+  ;; property from current headline.  Otherwise, the second argument
+  ;; is a search option to get the property from another headline.
+  (should
+   (equal "1"
+	  (org-test-with-temp-text
+	      "* H\n:PROPERTIES:\n:A: 1\n:END:\n{{{property(A)}}}<point>"
+	    (org-macro-initialize-templates)
+	    (org-macro-replace-all org-macro-templates)
+	    (buffer-substring-no-properties
+	     (line-beginning-position) (line-end-position)))))
+  (should
+   (equal "1"
+	  (org-test-with-temp-text
+	      "* H\n:PROPERTIES:\n:A: 1\n:END:\n{{{property(A,)}}}<point>"
+	    (org-macro-initialize-templates)
+	    (org-macro-replace-all org-macro-templates)
+	    (buffer-substring-no-properties
+	     (line-beginning-position) (line-end-position)))))
+  (should
+   (equal
+    "1"
+    (org-test-with-temp-text
+	"* H1\n:PROPERTIES:\n:A: 1\n:END:\n* H2\n{{{property(A,*H1)}}}<point>"
+      (org-macro-initialize-templates)
+      (org-macro-replace-all org-macro-templates)
+      (buffer-substring-no-properties
+       (line-beginning-position) (line-end-position)))))
+  (should-error
+   (org-test-with-temp-text
+       "* H1\n:PROPERTIES:\n:A: 1\n:END:\n* H2\n{{{property(A,*???)}}}<point>"
+     (org-macro-initialize-templates)
+     (org-macro-replace-all org-macro-templates))))
 
 (ert-deftest test-org-macro/escape-arguments ()
   "Test `org-macro-escape-arguments' specifications."