Browse Source

org-macro: Properly handle macros in setup files

* lisp/org-macro.el (org-macro--collect-macros): Fix a bug where
  reading a macro in a setup file would remove other macros read so
  far from template.  Change function signature.
(org-macro-initialize-templates): Apply signature change from function
above.
* testing/lisp/test-org-macro.el: Add test.
Nicolas Goaziou 12 years ago
parent
commit
a82b06ae4b
2 changed files with 43 additions and 35 deletions
  1. 38 31
      lisp/org-macro.el
  2. 5 4
      testing/lisp/test-org-macro.el

+ 38 - 31
lisp/org-macro.el

@@ -61,37 +61,44 @@ directly, use instead:
 
 ;;; Functions
 
-(defun org-macro--collect-macros (files)
+(defun org-macro--collect-macros ()
   "Collect macro definitions in current buffer and setup files.
-FILES is a list of setup files names read so far, used to avoid
-circular dependencies.  Return an alist containing all macro
-templates found."
-  (let ((case-fold-search t) templates)
-    ;; Install buffer-local macros.  Also enter SETUPFILE keywords.
-    (org-with-wide-buffer
-     (goto-char (point-min))
-     (while (re-search-forward "^[ \t]*#\\+\\(MACRO\\|SETUPFILE\\):" nil t)
-       (let ((element (org-element-at-point)))
-	 (when (eq (org-element-type element) 'keyword)
-	   (let ((val (org-element-property :value element)))
-	     (if (equal (org-element-property :key element) "SETUPFILE")
-		 ;; Enter setup file.
-		 (let ((file (expand-file-name (org-remove-double-quotes val))))
-		   (unless (member file files)
-		     (with-temp-buffer
-		       (org-mode)
-		       (insert (org-file-contents file 'noerror))
-		       (setq templates
-			     (org-macro--collect-macros (cons file files))))))
-	       ;; Install macro in TEMPLATES.
-	       (when (string-match "^\\(.*?\\)\\(?:\\s-+\\(.*\\)\\)?\\s-*$" val)
-		 (let* ((name (match-string 1 val))
-			(template (or (match-string 2 val) ""))
-			(old-cell (assoc name templates)))
-		   (if old-cell (setcdr old-cell template)
-		     (push (cons name template) templates))))))))))
-    ;; Return value.
-    templates))
+Return an alist containing all macro templates found."
+  (let* (collect-macros			; For byte-compiler.
+	 (collect-macros
+	  (lambda (files templates)
+	    ;; Return an alist of macro templates.  FILES is a list of
+	    ;; setup files names read so far, used to avoid circular
+	    ;; dependencies.  TEMPLATES is the alist collected so far.
+	    (let ((case-fold-search t))
+	      (org-with-wide-buffer
+	       (goto-char (point-min))
+	       (while (re-search-forward
+		       "^[ \t]*#\\+\\(MACRO\\|SETUPFILE\\):" nil t)
+		 (let ((element (org-element-at-point)))
+		   (when (eq (org-element-type element) 'keyword)
+		     (let ((val (org-element-property :value element)))
+		       (if (equal (org-element-property :key element) "MACRO")
+			   ;; Install macro in TEMPLATES.
+			   (when (string-match
+				  "^\\(.*?\\)\\(?:\\s-+\\(.*\\)\\)?\\s-*$" val)
+			     (let* ((name (match-string 1 val))
+				    (template (or (match-string 2 val) ""))
+				    (old-cell (assoc name templates)))
+			       (if old-cell (setcdr old-cell template)
+				 (push (cons name template) templates))))
+			 ;; Enter setup file.
+			 (let ((file (expand-file-name
+				      (org-remove-double-quotes val))))
+			   (unless (member file files)
+			     (with-temp-buffer
+			       (org-mode)
+			       (insert (org-file-contents file 'noerror))
+			       (setq templates
+				     (funcall collect-macros (cons file files)
+					      templates)))))))))))
+	      templates))))
+    (funcall collect-macros nil nil)))
 
 (defun org-macro-initialize-templates ()
   "Collect macro templates defined in current buffer.
@@ -100,7 +107,7 @@ Templates are stored in buffer-local variable
 function installs the following ones: \"property\",
 \"time\". and, if the buffer is associated to a file,
 \"input-file\" and \"modification-time\"."
-  (let* ((templates (org-macro--collect-macros nil))
+  (let* ((templates (org-macro--collect-macros))
 	 (update-templates
 	  (lambda (cell)
 	    (let ((old-template (assoc (car cell) templates)))

+ 5 - 4
testing/lisp/test-org-macro.el

@@ -66,11 +66,12 @@
   ;; Macros in setup file.
   (should
    (string-match
-    "success\\'"
+    "success success\\'"
     (org-test-with-temp-text
-	(format
-	 "#+SETUPFILE: \"%sexamples/macro-templates.org\"\n{{{included-macro}}}"
-	 org-test-dir)
+	(format "#+MACRO: other-macro success
+#+SETUPFILE: \"%sexamples/macro-templates.org\"
+{{{included-macro}}} {{{other-macro}}}"
+		org-test-dir)
       (org-macro-initialize-templates)
       (org-macro-replace-all org-macro-templates)
       (buffer-string)))))