summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <mail@nicolasgoaziou.fr>2015-05-10 11:48:13 +0200
committerNicolas Goaziou <mail@nicolasgoaziou.fr>2015-05-10 11:48:13 +0200
commitfa5f8c8f90440ce7e440148e2b7ee20a10d9f547 (patch)
treea9bc2d8e4d58cb224fffb8cd2e7f30a798358fbd
parentecc8b9f3db1cdc45534203cf4e9d04bc0705063f (diff)
downloadorg-mode-fa5f8c8f90440ce7e440148e2b7ee20a10d9f547.tar.gz
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.
-rw-r--r--doc/org.texi60
-rw-r--r--lisp/org-macro.el12
-rw-r--r--testing/lisp/test-org-macro.el35
3 files changed, 86 insertions, 21 deletions
diff --git a/doc/org.texi b/doc/org.texi
index d926de4..b515963 100644
--- a/doc/org.texi
+++ b/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
diff --git a/lisp/org-macro.el b/lisp/org-macro.el
index 890f0cf..a168ffb 100644
--- a/lisp/org-macro.el
+++ b/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))
diff --git a/testing/lisp/test-org-macro.el b/testing/lisp/test-org-macro.el
index d28cb7f..4934d93 100644
--- a/testing/lisp/test-org-macro.el
+++ b/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."