diff options
author | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2017-06-08 15:04:55 +0200 |
---|---|---|
committer | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2017-06-08 15:04:55 +0200 |
commit | 8e8094b91926ce3f591460a3c912bda333cf6f8a (patch) | |
tree | c52c945219e353a7efe9c09779d6383433782acb | |
parent | 3e11697ead9c2699755bd744c05b915c400be093 (diff) | |
parent | 3cf6345b408803486f72c524654439401e716493 (diff) | |
download | org-mode-8e8094b91926ce3f591460a3c912bda333cf6f8a.tar.gz |
Merge branch 'maint'
-rw-r--r-- | lisp/org-macro.el | 85 | ||||
-rw-r--r-- | testing/lisp/test-org-macro.el | 157 | ||||
-rw-r--r-- | testing/lisp/test-ox.el | 9 |
3 files changed, 131 insertions, 120 deletions
diff --git a/lisp/org-macro.el b/lisp/org-macro.el index dbfd6ad..dcf4e6e 100644 --- a/lisp/org-macro.el +++ b/lisp/org-macro.el @@ -199,47 +199,50 @@ as strings, where macro expansion is allowed." (format "\\`EXPORT_%s\\+?\\'" (regexp-opt keywords))) record) (while (re-search-forward "{{{[-A-Za-z0-9_]" nil t) - (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))))))))))) + (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 c5f001a..7356e98 100644 --- a/testing/lisp/test-org-macro.el +++ b/testing/lisp/test-org-macro.el @@ -30,33 +30,33 @@ "#+MACRO: A B\n1 B 3" (org-test-with-temp-text "#+MACRO: A B\n1 {{{A}}} 3" (progn (org-macro-initialize-templates) - (org-macro-replace-all org-macro-templates) - (buffer-string))))) + (org-macro-replace-all org-macro-templates) + (buffer-string))))) ;; Macro with arguments. (should (equal "#+MACRO: macro $1 $2\nsome text" (org-test-with-temp-text "#+MACRO: macro $1 $2\n{{{macro(some,text)}}}" (progn (org-macro-initialize-templates) - (org-macro-replace-all org-macro-templates) - (buffer-string))))) + (org-macro-replace-all org-macro-templates) + (buffer-string))))) ;; Macro with "eval". (should (equal "#+MACRO: add (eval (+ $1 $2))\n3" (org-test-with-temp-text "#+MACRO: add (eval (+ $1 $2))\n{{{add(1,2)}}}" (progn (org-macro-initialize-templates) - (org-macro-replace-all org-macro-templates) - (buffer-string))))) + (org-macro-replace-all org-macro-templates) + (buffer-string))))) ;; Nested macros. (should (equal "#+MACRO: in inner\n#+MACRO: out {{{in}}} outer\ninner outer" (org-test-with-temp-text - "#+MACRO: in inner\n#+MACRO: out {{{in}}} outer\n{{{out}}}" + "#+MACRO: in inner\n#+MACRO: out {{{in}}} outer\n{{{out}}}" (progn (org-macro-initialize-templates) - (org-macro-replace-all org-macro-templates) - (buffer-string))))) + (org-macro-replace-all org-macro-templates) + (buffer-string))))) ;; Error out when macro expansion is circular. (should-error (org-test-with-temp-text @@ -68,10 +68,10 @@ (string-match "success success\\'" (org-test-with-temp-text - (format "#+MACRO: other-macro success + (format "#+MACRO: other-macro success #+SETUPFILE: \"%sexamples/macro-templates.org\" {{{included-macro}}} {{{other-macro}}}" - org-test-dir) + org-test-dir) (org-macro-initialize-templates) (org-macro-replace-all org-macro-templates) (buffer-string)))) @@ -80,10 +80,27 @@ (string-match-p "{{{macro}}}" (org-test-with-temp-text - "#+MACRO: macro expansion\n{{{macro}}}\n<point>Contents" + "#+MACRO: macro expansion\n{{{macro}}}\n<point>Contents" (narrow-to-region (point) (point-max)) (org-macro-initialize-templates) (org-macro-replace-all org-macro-templates) + (org-with-wide-buffer (buffer-string))))) + ;; Macros in a commented tree are not expanded. + (should + (string-match-p + "{{{macro}}}" + (org-test-with-temp-text + "#+MACRO: macro expansion\n* COMMENT H\n<point>{{{macro}}}" + (org-macro-initialize-templates) + (org-macro-replace-all org-macro-templates) + (org-with-wide-buffer (buffer-string))))) + (should + (string-match-p + "{{{macro}}}" + (org-test-with-temp-text + "#+MACRO: macro expansion\n* COMMENT H1\n** H2\n<point>{{{macro}}}" + (org-macro-initialize-templates) + (org-macro-replace-all org-macro-templates) (org-with-wide-buffer (buffer-string)))))) (ert-deftest test-org-macro/property () @@ -93,25 +110,25 @@ ;; 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))))) + (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))))) + (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>" + "* 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 @@ -127,73 +144,73 @@ ;; Standard test with default counter. (should (equal "1 2" - (org-test-with-temp-text "{{{n}}} {{{n}}}" - (org-macro-initialize-templates) - (org-macro-replace-all org-macro-templates) - (buffer-substring-no-properties - (line-beginning-position) (line-end-position))))) + (org-test-with-temp-text "{{{n}}} {{{n}}}" + (org-macro-initialize-templates) + (org-macro-replace-all org-macro-templates) + (buffer-substring-no-properties + (line-beginning-position) (line-end-position))))) (should (equal "1 2" - (org-test-with-temp-text "{{{n()}}} {{{n}}}" - (org-macro-initialize-templates) - (org-macro-replace-all org-macro-templates) - (buffer-substring-no-properties - (line-beginning-position) (line-end-position))))) + (org-test-with-temp-text "{{{n()}}} {{{n}}}" + (org-macro-initialize-templates) + (org-macro-replace-all org-macro-templates) + (buffer-substring-no-properties + (line-beginning-position) (line-end-position))))) ;; Test alternative counters. (should (equal "1 1 1 2" - (org-test-with-temp-text "{{{n}}} {{{n(c1)}}} {{{n(c2)}}} {{{n(c1)}}}" - (org-macro-initialize-templates) - (org-macro-replace-all org-macro-templates) - (buffer-substring-no-properties - (line-beginning-position) (line-end-position))))) + (org-test-with-temp-text "{{{n}}} {{{n(c1)}}} {{{n(c2)}}} {{{n(c1)}}}" + (org-macro-initialize-templates) + (org-macro-replace-all org-macro-templates) + (buffer-substring-no-properties + (line-beginning-position) (line-end-position))))) ;; Second argument set a counter to a given value. A non-numeric ;; value resets the counter to 1. (should (equal "9 10" - (org-test-with-temp-text "{{{n(c,9)}}} {{{n(c)}}}" - (org-macro-initialize-templates) - (org-macro-replace-all org-macro-templates) - (buffer-substring-no-properties - (line-beginning-position) (line-end-position))))) + (org-test-with-temp-text "{{{n(c,9)}}} {{{n(c)}}}" + (org-macro-initialize-templates) + (org-macro-replace-all org-macro-templates) + (buffer-substring-no-properties + (line-beginning-position) (line-end-position))))) (should (equal "9 1" - (org-test-with-temp-text "{{{n(c,9)}}} {{{n(c,reset)}}}" - (org-macro-initialize-templates) - (org-macro-replace-all org-macro-templates) - (buffer-substring-no-properties - (line-beginning-position) (line-end-position))))) + (org-test-with-temp-text "{{{n(c,9)}}} {{{n(c,reset)}}}" + (org-macro-initialize-templates) + (org-macro-replace-all org-macro-templates) + (buffer-substring-no-properties + (line-beginning-position) (line-end-position))))) ;; Tolerate spaces in second argument. (should (equal "9 10" - (org-test-with-temp-text "{{{n(c, 9)}}} {{{n(c)}}}" - (org-macro-initialize-templates) - (org-macro-replace-all org-macro-templates) - (buffer-substring-no-properties - (line-beginning-position) (line-end-position))))) + (org-test-with-temp-text "{{{n(c, 9)}}} {{{n(c)}}}" + (org-macro-initialize-templates) + (org-macro-replace-all org-macro-templates) + (buffer-substring-no-properties + (line-beginning-position) (line-end-position))))) (should (equal "9 1" - (org-test-with-temp-text "{{{n(c,9)}}} {{{n(c, reset)}}}" - (org-macro-initialize-templates) - (org-macro-replace-all org-macro-templates) - (buffer-substring-no-properties - (line-beginning-position) (line-end-position))))) + (org-test-with-temp-text "{{{n(c,9)}}} {{{n(c, reset)}}}" + (org-macro-initialize-templates) + (org-macro-replace-all org-macro-templates) + (buffer-substring-no-properties + (line-beginning-position) (line-end-position))))) ;; Second argument also applies to default counter. (should (equal "9 10 1" - (org-test-with-temp-text "{{{n(,9)}}} {{{n}}} {{{n(,reset)}}}" - (org-macro-initialize-templates) - (org-macro-replace-all org-macro-templates) - (buffer-substring-no-properties - (line-beginning-position) (line-end-position))))) + (org-test-with-temp-text "{{{n(,9)}}} {{{n}}} {{{n(,reset)}}}" + (org-macro-initialize-templates) + (org-macro-replace-all org-macro-templates) + (buffer-substring-no-properties + (line-beginning-position) (line-end-position))))) ;; An empty second argument is equivalent to no argument. (should (equal "2 3" - (org-test-with-temp-text "{{{n(c,2)}}} {{{n(c,)}}}" - (org-macro-initialize-templates) - (org-macro-replace-all org-macro-templates) - (buffer-substring-no-properties - (line-beginning-position) (line-end-position)))))) + (org-test-with-temp-text "{{{n(c,2)}}} {{{n(c,)}}}" + (org-macro-initialize-templates) + (org-macro-replace-all org-macro-templates) + (buffer-substring-no-properties + (line-beginning-position) (line-end-position)))))) (ert-deftest test-org-macro/escape-arguments () "Test `org-macro-escape-arguments' specifications." diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el index 33792e6..b18b0ae 100644 --- a/testing/lisp/test-ox.el +++ b/testing/lisp/test-ox.el @@ -1399,15 +1399,6 @@ Footnotes[fn:2], foot[fn:test] and [fn:inline:inline footnote] ;; Throw an error when a macro definition is missing. (should-error (org-test-with-temp-text "{{{missing}}}" - (org-export-as (org-test-default-backend)))) - ;; Macros defined in commented subtrees are ignored. - (should-error - (org-test-with-temp-text - "* COMMENT H\n#+MACRO: macro1\n* H2\nvalue\n{{{macro1}}}" - (org-export-as (org-test-default-backend)))) - (should-error - (org-test-with-temp-text - "* COMMENT H\n** H2\n#+MACRO: macro1\n* H3\nvalue\n{{{macro1}}}" (org-export-as (org-test-default-backend))))) (ert-deftest test-org-export/before-processing-hook () |