Sfoglia il codice sorgente

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
Nicolas Goaziou 7 anni fa
parent
commit
5f5d82ed51
2 ha cambiato i file con 49 aggiunte e 33 eliminazioni
  1. 46 7
      lisp/org-macro.el
  2. 3 26
      lisp/ox.el

+ 46 - 7
lisp/org-macro.el

@@ -136,6 +136,25 @@ function installs the following ones: \"property\",
 	    (let ((old-template (assoc (car cell) templates)))
 	    (let ((old-template (assoc (car cell) templates)))
 	      (if old-template (setcdr old-template (cdr cell))
 	      (if old-template (setcdr old-template (cdr cell))
 		(push cell templates))))))
 		(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.
     ;; Install "property", "time" macros.
     (mapc update-templates
     (mapc update-templates
 	  (list (cons "property"
 	  (list (cons "property"
@@ -156,7 +175,11 @@ function installs the following ones: \"property\",
 	(mapc update-templates
 	(mapc update-templates
 	      (list (cons "input-file" (file-name-nondirectory visited-file))
 	      (list (cons "input-file" (file-name-nondirectory visited-file))
 		    (cons "modification-time"
 		    (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 visited-file)
 				  (prin1-to-string
 				  (prin1-to-string
 				   (nth 5 (file-attributes visited-file)))))))))
 				   (nth 5 (file-attributes visited-file)))))))))
@@ -190,17 +213,17 @@ default value.  Return nil if no template was found."
         ;; Return string.
         ;; Return string.
         (format "%s" (or value ""))))))
         (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.
   "Replace all macros in current buffer by their expansion.
 
 
 TEMPLATES is an alist of templates used for expansion.  See
 TEMPLATES is an alist of templates used for expansion.  See
 `org-macro-templates' for a buffer-local default value.
 `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,
 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
   (org-with-wide-buffer
    (goto-char (point-min))
    (goto-char (point-min))
    (let ((properties-regexp (format "\\`EXPORT_%s\\+?\\'"
    (let ((properties-regexp (format "\\`EXPORT_%s\\+?\\'"
@@ -246,7 +269,7 @@ as strings, where macro expansion is allowed."
 		      ;; Leave point before replacement in case of
 		      ;; Leave point before replacement in case of
 		      ;; recursive expansions.
 		      ;; recursive expansions.
 		      (save-excursion (insert value)))
 		      (save-excursion (insert value)))
-		     (finalize
+		     (t
 		      (error "Undefined Org macro: %s; aborting"
 		      (error "Undefined Org macro: %s; aborting"
 			     (org-element-property :key macro))))))))))))
 			     (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
 ;;; 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)
 (defun org-macro--vc-modified-time (file)
   (save-window-excursion
   (save-window-excursion
     (when (vc-backend file)
     (when (vc-backend file)

+ 3 - 26
lisp/ox.el

@@ -3038,9 +3038,9 @@ Return code as a string."
 	 (org-export-expand-include-keyword)
 	 (org-export-expand-include-keyword)
 	 (org-export--delete-comment-trees)
 	 (org-export--delete-comment-trees)
 	 (org-macro-initialize-templates)
 	 (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
 	 ;; Refresh buffer properties and radio targets after
 	 ;; potentially invasive previous changes.  Likewise, do it
 	 ;; potentially invasive previous changes.  Likewise, do it
 	 ;; again after executing Babel code.
 	 ;; again after executing Babel code.
@@ -3082,29 +3082,6 @@ Return code as a string."
 	   (dolist (filter (plist-get info :filter-options))
 	   (dolist (filter (plist-get info :filter-options))
 	     (let ((result (funcall filter info backend-name)))
 	     (let ((result (funcall filter info backend-name)))
 	       (when result (setq info result)))))
 	       (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.
 	 ;; Parse buffer.
 	 (setq tree (org-element-parse-buffer nil visible-only))
 	 (setq tree (org-element-parse-buffer nil visible-only))
 	 ;; Prune tree from non-exported elements and transform
 	 ;; Prune tree from non-exported elements and transform