diff options
author | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2017-08-21 21:27:06 +0200 |
---|---|---|
committer | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2017-08-21 21:27:06 +0200 |
commit | 526b3d4b980317ef176869011b9b152ef85b5258 (patch) | |
tree | 6e55c081375d354aeae61b016465b856ece6a515 | |
parent | e40d2df6808ab803247270a5620253a216948539 (diff) | |
parent | 6980b02b6f592d948dc1b4394ccba882c2140907 (diff) | |
download | org-mode-526b3d4b980317ef176869011b9b152ef85b5258.tar.gz |
Merge branch 'maint'
-rw-r--r-- | lisp/org-macro.el | 98 | ||||
-rw-r--r-- | testing/lisp/test-org-macro.el | 37 |
2 files changed, 83 insertions, 52 deletions
diff --git a/lisp/org-macro.el b/lisp/org-macro.el index 67d71b0..3453e5e 100644 --- a/lisp/org-macro.el +++ b/lisp/org-macro.el @@ -201,56 +201,54 @@ 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." - (save-excursion - (goto-char (point-min)) - (let ((properties-regexp - (format "\\`EXPORT_%s\\+?\\'" (regexp-opt keywords))) - record) - (while (re-search-forward "{{{[-A-Za-z0-9_]" nil t) - (unless (save-match-data (org-in-commented-heading-p)) - (let* ((datum (save-match-data (org-element-context))) - (type (org-element-type datum)) - (macro - (cond - ((eq type 'macro) datum) - ;; In parsed keywords and associated node - ;; properties, force macro recognition. - ((or (and (eq type 'keyword) - (member (org-element-property :key datum) - keywords)) - (and (eq type 'node-property) - (string-match-p properties-regexp - (org-element-property :key - datum)))) - (save-excursion - (goto-char (match-beginning 0)) - (org-element-macro-parser)))))) - (when macro - (let* ((value (org-macro-expand macro templates)) - (begin (org-element-property :begin macro)) - (signature (list begin - macro - (org-element-property :args macro)))) - ;; Avoid circular dependencies by checking if the same - ;; macro with the same arguments is expanded at the - ;; same position twice. - (cond ((member signature record) - (error "Circular macro expansion: %s" - (org-element-property :key macro))) - (value - (push signature record) - (delete-region - begin - ;; Preserve white spaces after the macro. - (progn (goto-char (org-element-property :end macro)) - (skip-chars-backward " \t") - (point))) - ;; Leave point before replacement in case of - ;; recursive expansions. - (save-excursion (insert value))) - (finalize - (error "Undefined Org macro: %s; aborting" - (org-element-property :key macro)))))))))))) + (org-with-wide-buffer + (goto-char (point-min)) + (let ((properties-regexp (format "\\`EXPORT_%s\\+?\\'" + (regexp-opt keywords))) + record) + (while (re-search-forward "{{{[-A-Za-z0-9_]" nil t) + (unless (save-match-data (org-in-commented-heading-p)) + (let* ((datum (save-match-data (org-element-context))) + (type (org-element-type datum)) + (macro + (cond + ((eq type 'macro) datum) + ;; In parsed keywords and associated node + ;; properties, force macro recognition. + ((or (and (eq type 'keyword) + (member (org-element-property :key datum) keywords)) + (and (eq type 'node-property) + (string-match-p properties-regexp + (org-element-property :key datum)))) + (save-excursion + (goto-char (match-beginning 0)) + (org-element-macro-parser)))))) + (when macro + (let* ((value (org-macro-expand macro templates)) + (begin (org-element-property :begin macro)) + (signature (list begin + macro + (org-element-property :args macro)))) + ;; Avoid circular dependencies by checking if the same + ;; macro with the same arguments is expanded at the + ;; same position twice. + (cond ((member signature record) + (error "Circular macro expansion: %s" + (org-element-property :key macro))) + (value + (push signature record) + (delete-region + begin + ;; Preserve white spaces after the macro. + (progn (goto-char (org-element-property :end macro)) + (skip-chars-backward " \t") + (point))) + ;; Leave point before replacement in case of + ;; recursive expansions. + (save-excursion (insert value))) + (finalize + (error "Undefined Org macro: %s; aborting" + (org-element-property :key macro)))))))))))) (defun org-macro-escape-arguments (&rest args) "Build macro's arguments string from ARGS. diff --git a/testing/lisp/test-org-macro.el b/testing/lisp/test-org-macro.el index 664bc88..5650dca 100644 --- a/testing/lisp/test-org-macro.el +++ b/testing/lisp/test-org-macro.el @@ -75,10 +75,43 @@ (org-macro-initialize-templates) (org-macro-replace-all org-macro-templates) (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))) ;; Macro expansion ignores narrowing. (should - (string-match-p - "{{{macro}}}" + (string-match + "expansion" (org-test-with-temp-text "#+MACRO: macro expansion\n{{{macro}}}\n<point>Contents" (narrow-to-region (point) (point-max)) |