Browse Source

ox.el: {{{date}}} formatting argument

* ox.el (org-export-as): Allow {{{date}}} to take formatting-argument.
* org.texi (Macro replacement): Document {{{date}}} formatting.
* test-ox.el (test-org-export/expand-macro): Test {{{data(format)}}}
* org-NEWS: Mention optional {{{data}}} argument.

Optional argument to {{{date}}} like {{{date(FMT)}}} are treated
similar to {{{time(FMT)}}} if \#+DATE is a timestamp.
Rasmus 10 years ago
parent
commit
8f38f037b4
4 changed files with 42 additions and 13 deletions
  1. 11 8
      doc/org.texi
  2. 3 0
      etc/ORG-NEWS
  3. 17 4
      lisp/ox.el
  4. 11 1
      testing/lisp/test-ox.el

+ 11 - 8
doc/org.texi

@@ -10130,14 +10130,17 @@ are allowed in @code{#+CAPTION}, @code{#+TITLE}, @code{#+AUTHOR} and
 @code{#+EMAIL}.
 
 In addition to user-defined macros, a set of predefined macros can be used:
-@code{@{@{@{title@}@}@}}, @code{@{@{@{author@}@}@}}, @code{@{@{@{date@}@}}
-and @code{@{@{@{email@}@}} are replaced with the information set by the
-respective keywords.  Further, @code{@{@{@{time(@var{FORMAT})@}@}@}} and
-@code{@{@{@{modification-time(@var{FORMAT})@}@}@}} refer to the current date
-and to the modification time of the file being exported, respectively.
-@var{FORMAT} should be a format string understood by
-@code{format-time-string}.  Finally, the filename is available via
-@code{@{@{@{input-file@}@}@}} and properties can be inserted using
+@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})@}@}@}}.
 
 The surrounding brackets can be made invisible by setting

+ 3 - 0
etc/ORG-NEWS

@@ -198,6 +198,9 @@ countdown timers.
 *** New option ~only-window~ for ~org-agenda-window-setup~
 When ~org-agenda-window-setup~ is set to ~only-window~, the agenda is
 displayed as the sole window of the current frame.
+*** ~{{{date}}}~ macro supports optional formatting argument
+It is now possible to supply and optional formatting argument to
+~{{{date}}}~. See manual for details.
 ** Miscellaneous
 *** Strip all meta data from ITEM special property
 ITEM special property does not contain TODO, priority or tags anymore.

+ 17 - 4
lisp/ox.el

@@ -2865,14 +2865,27 @@ Return code as a string."
 	     (let ((result (funcall filter info backend-name)))
 	       (when result (setq info result)))))
 	 ;; Expand export-specific set of macros: {{{author}}},
-	 ;; {{{date}}}, {{{email}}} and {{{title}}}.  It must be done
-	 ;; once regular macros have been expanded, since document
-	 ;; keywords may contain one of them.
+	 ;; {{{date(FORMAT)}}}, {{{email}}} and {{{title}}}.  It must
+	 ;; be done once regular macros have been expanded, since
+	 ;; document keywords may contain one of them.
 	 (org-macro-replace-all
 	  (list (cons "author"
 		      (org-element-interpret-data (plist-get info :author)))
 		(cons "date"
-		      (org-element-interpret-data (plist-get info :date)))
+		      (let* ((date (plist-get info :date))
+			     (value (or (org-element-interpret-data date) "")))
+			(if (and (not (cdr date))
+				 (eq (org-element-type (car date)) 'timestamp))
+			    (format "(eval (if (org-string-nw-p \"$1\") %s %S))"
+				    (format "(org-timestamp-format '%S \"$1\")"
+					    ;; Remove parent to avoid
+					    ;; read error.
+					    `(timestamp
+					      ,(org-combine-plists
+						(nth 1 (car date))
+						'(:parent nil))))
+				    value)
+			  value)))
 		;; EMAIL is not a parsed keyword: store it as-is.
 		(cons "email" (or (plist-get info :email) ""))
 		(cons "title"

+ 11 - 1
testing/lisp/test-ox.el

@@ -1104,7 +1104,17 @@ Footnotes[fn:2], foot[fn:test], digit only[3], and [fn:inline:anonymous footnote
 	      (format "#+INCLUDE: \"%s/examples/macro-templates.org\"
 {{{included-macro}}}" org-test-dir)
 	    (let ((output (org-export-as (org-test-default-backend))))
-	      (substring output (string-match ".*\n\\'" output)))))))
+	      (substring output (string-match ".*\n\\'" output))))))
+  ;; Date macro takes a optional formatting argument
+  (should
+   (equal "09-02-15\n"
+    (org-test-with-temp-text "{{{date(%d-%m-%y)}}}\n* d :noexport:\n#+DATE: <2015-02-09>"
+      (org-export-as (org-test-default-backend)))))
+  ;; Only single timestamps are formatted
+  (should
+   (equal "<2015-02x-09>\n"
+    (org-test-with-temp-text "{{{date(%d-%m-%y)}}}\n* d :noexport:\n#+DATE: <2015-02x-09>"
+      (org-export-as (org-test-default-backend))))))
 
 (ert-deftest test-org-export/before-processing-hook ()
   "Test `org-export-before-processing-hook'."