diff --git a/doc/org.texi b/doc/org.texi index 671130400..52fc859eb 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -10790,13 +10790,15 @@ Visit the include file at point. @cindex macro replacement, during export @cindex #+MACRO -You can define text snippets with +@vindex org-export-global-macros +Macros replace text snippets during export. Macros are defined globally in +@code{org-export-global-macros}, or document-wise with the following syntax: @example #+MACRO: name replacement text $1, $2 are arguments @end example -@noindent which can be referenced +@noindent which can be referenced using @code{@{@{@{name(arg1, arg2)@}@}@}}@footnote{Since commas separate arguments, commas within arguments have to be escaped with a backslash character. Conversely, backslash characters before a comma, and only them, need to be diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 0058b7dd9..dceecfefd 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -126,6 +126,8 @@ Where clue > 0 This new function is meant to be used in back-ends supporting images as descriptions of links, a.k.a. image links. See its docstring for details. +**** Add global macros through ~org-export-global-macros~ +With this variable, one can define macros available for all documents. **** Horizontal rules are no longer ignored in LaTeX table math mode *** ~org-list-to-generic~ includes a new property: ~:ifmt~ @@ -149,8 +151,6 @@ For an equivalent to a ~nil~ value, set ~org-agenda-show-future-repeats~ to nil and ~org-agenda-prefer-last-repeat~ to ~t~. -** Removed options - *** ~org-publish-sitemap-file-entry-format~ is deprecated One can provide new ~:sitemap-format-entry~ property for a function diff --git a/lisp/ox.el b/lisp/ox.el index 5e361792f..e2ad885b3 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -883,6 +883,29 @@ HTML code while every other back-end will ignore it." (cl-every #'stringp (mapcar #'car x)) (cl-every #'stringp (mapcar #'cdr x))))) +(defcustom org-export-global-macros nil + "Alist between macro names and expansion templates. + +This variable defines macro expansion templates available +globally. Associations follow the pattern + + (NAME . TEMPLATE) + +where NAME is a string beginning with a letter and consisting of +alphanumeric characters only. + +TEMPLATE is the string to which the macro is going to be +expanded. Inside, \"$1\", \"$2\"... are place-holders for +macro's arguments. Moreover, if the template starts with +\"(eval\", it will be parsed as an Elisp expression and evaluated +accordingly." + :group 'org-export-general + :version "25.2" + :package-version '(Org . "9.1") + :type '(repeat + (cons (string :tag "Name") + (string :tag "Template")))) + (defcustom org-export-coding-system nil "Coding system for the exported file." :group 'org-export-general @@ -3046,7 +3069,9 @@ Return code as a string." (org-export-expand-include-keyword) (org-export--delete-comments) (org-macro-initialize-templates) - (org-macro-replace-all org-macro-templates nil parsed-keywords) + (org-macro-replace-all + (append org-macro-templates org-export-global-macros) + nil parsed-keywords) ;; Refresh buffer properties and radio targets after ;; potentially invasive previous changes. Likewise, do it ;; again after executing Babel code. diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el index 72ecc4ccc..c1fbcda84 100644 --- a/testing/lisp/test-ox.el +++ b/testing/lisp/test-ox.el @@ -1255,6 +1255,27 @@ Footnotes[fn:2], foot[fn:test] and [fn:inline:inline footnote] (equal "#+MACRO: macro1 value\nvalue\n" (org-test-with-temp-text "#+MACRO: macro1 value\n{{{macro1}}}" (org-export-as (org-test-default-backend))))) + ;; Include global macros. However, local macros override them. + (should + (equal "global\n" + (org-test-with-temp-text "{{{M}}}" + (let ((org-export-global-macros '(("M" . "global")))) + (org-export-as (org-test-default-backend)))))) + (should + (equal "global arg\n" + (org-test-with-temp-text "{{{M(arg)}}}" + (let ((org-export-global-macros '(("M" . "global $1")))) + (org-export-as (org-test-default-backend)))))) + (should + (equal "2\n" + (org-test-with-temp-text "{{{M}}}" + (let ((org-export-global-macros '(("M" . "(eval (+ 1 1))")))) + (org-export-as (org-test-default-backend)))))) + (should + (equal "#+MACRO: M local\nlocal\n" + (org-test-with-temp-text "#+macro: M local\n{{{M}}}" + (let ((org-export-global-macros '(("M" . "global")))) + (org-export-as (org-test-default-backend)))))) ;; Allow macro in parsed keywords and associated properties. ;; Standard macro expansion. (should