Function: org-macro-replace-all
org-macro-replace-all is a byte-compiled function defined in
org-macro.el.gz.
Signature
(org-macro-replace-all TEMPLATES &optional KEYWORDS)
Documentation
Replace all macros in current buffer by their expansion.
TEMPLATES is an alist of templates used for expansion. See
org-macro-templates for a buffer-local default value.
Optional argument KEYWORDS, when non-nil is a list of keywords, as strings, where macro expansion is allowed.
Return an error if a macro in the buffer cannot be associated to a definition in TEMPLATES.
Source Code
;; Defined in /usr/src/emacs/lisp/org/org-macro.el.gz
(defun org-macro-replace-all (templates &optional keywords)
"Replace all macros in current buffer by their expansion.
TEMPLATES is an alist of templates used for expansion. See
`org-macro-templates' for a buffer-local default value.
Optional argument KEYWORDS, when non-nil is a list of keywords,
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
(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
;; `:parent' property might change as we modify buffer.
;; We do not care about it when checking for circular
;; dependencies. So, setting `:parent' to nil making sure
;; that actual macro element (if org-element-cache is
;; active) is unchanged.
(setq macro (cl-copy-list macro))
(org-element-put-property macro :parent nil)
(let* ((key (org-element-property :key macro))
(value (org-macro-expand macro templates))
(begin (org-element-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" key))
(value
(push signature record)
(delete-region
begin
;; Preserve white spaces after the macro.
(progn (goto-char (org-element-end macro))
(skip-chars-backward " \t")
(point)))
;; Leave point before replacement in case of
;; recursive expansions.
(save-excursion (insert value)))
;; Special "results" macro: if it is not defined,
;; simply leave it as-is. It will be expanded in
;; a second phase.
((equal key "results"))
(t
(error "Undefined Org macro: %s; aborting"
(org-element-property :key macro))))))))))))