summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <mail@nicolasgoaziou.fr>2017-11-21 22:25:17 +0100
committerNicolas Goaziou <mail@nicolasgoaziou.fr>2017-11-21 22:27:42 +0100
commit5f5d82ed516b7b385a9258271becbfa247e94af3 (patch)
treee552b8bf43df0de246d793ad442f0cb2f15e750f
parent7455f4bf83635e472104597e67f80c43f70ad051 (diff)
downloadorg-mode-5f5d82ed516b7b385a9258271becbfa247e94af3.tar.gz
Remove second pass for macro expansion
* lisp/org-macro.el (org-macro-initialize-templates): Initialize all macros, including {{{title}}} and al. (org-macro-replace-all): Change signature. (org-macro--find-keyword-value): New function. * lisp/ox.el (org-export-as): Remove second macro expansion
-rw-r--r--lisp/org-macro.el53
-rw-r--r--lisp/ox.el29
2 files changed, 49 insertions, 33 deletions
diff --git a/lisp/org-macro.el b/lisp/org-macro.el
index 1d2823e..f78eaf0 100644
--- a/lisp/org-macro.el
+++ b/lisp/org-macro.el
@@ -136,6 +136,25 @@ function installs the following ones: \"property\",
(let ((old-template (assoc (car cell) templates)))
(if old-template (setcdr old-template (cdr cell))
(push cell templates))))))
+ ;; Install "author, "date, "email", "title" and "results" macros.
+ (mapc update-templates
+ (list
+ (cons "author" (org-macro--find-keyword-value "AUTHOR"))
+ (cons "date"
+ (let* ((value (org-macro--find-keyword-value "DATE"))
+ (date (org-element-parse-secondary-string
+ value (org-element-restriction 'keyword))))
+ (if (and (consp date)
+ (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\")"
+ (org-element-copy (car date)))
+ value)
+ value)))
+ (cons "email" (org-macro--find-keyword-value "EMAIL"))
+ (cons "results" "$1")
+ (cons "title" (org-macro--find-keyword-value "TITLE"))))
;; Install "property", "time" macros.
(mapc update-templates
(list (cons "property"
@@ -156,7 +175,11 @@ function installs the following ones: \"property\",
(mapc update-templates
(list (cons "input-file" (file-name-nondirectory visited-file))
(cons "modification-time"
- (format "(eval (format-time-string \"$1\" (or (and (org-string-nw-p \"$2\") (org-macro--vc-modified-time %s)) '%s)))"
+ (format "(eval
+\(format-time-string \"$1\"
+ (or (and (org-string-nw-p \"$2\")
+ (org-macro--vc-modified-time %s))
+ '%s)))"
(prin1-to-string visited-file)
(prin1-to-string
(nth 5 (file-attributes visited-file)))))))))
@@ -190,17 +213,17 @@ default value. Return nil if no template was found."
;; Return string.
(format "%s" (or value ""))))))
-(defun org-macro-replace-all (templates &optional finalize keywords)
+(defun org-macro-replace-all (templates &optional keywords)
"Replace all macros in current buffer by their expansion.
TEMPLATES is an alist of templates used for expansion. See
`org-macro-templates' for a buffer-local default value.
-If optional arg FINALIZE is non-nil, raise an error if a macro is
-found in the buffer with no definition in TEMPLATES.
-
Optional argument KEYWORDS, when non-nil is a list of keywords,
-as strings, where macro expansion is allowed."
+as strings, where macro expansion is allowed.
+
+Return an error if a macro in the buffer cannot be associated to
+a definition in TEMPLATES."
(org-with-wide-buffer
(goto-char (point-min))
(let ((properties-regexp (format "\\`EXPORT_%s\\+?\\'"
@@ -246,7 +269,7 @@ as strings, where macro expansion is allowed."
;; Leave point before replacement in case of
;; recursive expansions.
(save-excursion (insert value)))
- (finalize
+ (t
(error "Undefined Org macro: %s; aborting"
(org-element-property :key macro))))))))))))
@@ -294,6 +317,22 @@ Return a list of arguments, as strings. This is the opposite of
;;; Helper functions and variables for internal macros
+(defun org-macro--find-keyword-value (name)
+ "Find value for keyword NAME in current buffer.
+KEYWORD is a string. Return value associated to the keywords
+named after NAME, as a string, or nil."
+ (org-with-point-at 1
+ (let ((regexp (format "^[ \t]*#\\+%s:" (regexp-quote name)))
+ (case-fold-search t)
+ (result nil))
+ (while (re-search-forward regexp nil t)
+ (let ((element (org-element-at-point)))
+ (when (eq 'keyword (org-element-type element))
+ (setq result (concat result
+ " "
+ (org-element-property :value element))))))
+ (and result (org-trim result)))))
+
(defun org-macro--vc-modified-time (file)
(save-window-excursion
(when (vc-backend file)
diff --git a/lisp/ox.el b/lisp/ox.el
index 7ab4128..db5594f 100644
--- a/lisp/ox.el
+++ b/lisp/ox.el
@@ -3038,9 +3038,9 @@ Return code as a string."
(org-export-expand-include-keyword)
(org-export--delete-comment-trees)
(org-macro-initialize-templates)
- (org-macro-replace-all
- (append org-macro-templates org-export-global-macros)
- nil parsed-keywords)
+ (org-macro-replace-all (append org-macro-templates
+ org-export-global-macros)
+ parsed-keywords)
;; Refresh buffer properties and radio targets after
;; potentially invasive previous changes. Likewise, do it
;; again after executing Babel code.
@@ -3082,29 +3082,6 @@ Return code as a string."
(dolist (filter (plist-get info :filter-options))
(let ((result (funcall filter info backend-name)))
(when result (setq info result)))))
- ;; Expand export-specific set of macros: {{{author}}},
- ;; {{{date(FORMAT)}}}, {{{email}}} and {{{title}}}. It must
- ;; be done once regular macros have been expanded, since
- ;; parsed keywords may contain one of them.
- (org-macro-replace-all
- (list
- (cons "author" (org-element-interpret-data (plist-get info :author)))
- (cons "date"
- (let* ((date (plist-get info :date))
- (value (or (org-element-interpret-data date) "")))
- (if (and (consp date)
- (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\")"
- (org-element-copy (car date)))
- value)
- value)))
- (cons "email" (org-element-interpret-data (plist-get info :email)))
- (cons "title" (org-element-interpret-data (plist-get info :title)))
- (cons "results" "$1"))
- 'finalize
- parsed-keywords)
;; Parse buffer.
(setq tree (org-element-parse-buffer nil visible-only))
;; Prune tree from non-exported elements and transform