forked from mirrors/org-mode
org-export: Use new API for macro expansion
* contrib/lisp/org-export.el (org-export-define-backend): Update docstring. (org-export-special-keywords): Remove "MACRO". (org-export--get-inbuffer-options, org-export--get-buffer-attributes): Remove internal macro handling. (org-export-as): Use external tool instead. (org-export-expand-macro): Remove function. * contrib/lisp/org-e-ascii.el (org-e-ascii-macro): Remove function. * contrib/lisp/org-e-groff.el (org-e-groff-macro): Remove function. * contrib/lisp/org-e-html.el (org-e-html-macro): Remove function. * contrib/lisp/org-e-latex.el (org-e-latex-macro): Remove function. * contrib/lisp/org-e-man.el (org-e-man-macro): Remove function. * contrib/lisp/org-e-odt.el (org-e-odt-macro): Remove function. * contrib/lisp/org-e-texinfo.el (org-e-texinfo-macro): Remove function. * testing/lisp/test-org-export.el: Remove tests. Since macros are now expanded before parsing (and produce Org syntax), back-ends will never see them (unless NO-EXPAND argument from `org-export-as' is non-nil, which isn't the case for any back-end so far).
This commit is contained in:
parent
4a2f3c2093
commit
ea77b2ccb2
|
@ -76,7 +76,6 @@
|
|||
(latex-fragment . org-e-ascii-latex-fragment)
|
||||
(line-break . org-e-ascii-line-break)
|
||||
(link . org-e-ascii-link)
|
||||
(macro . org-e-ascii-macro)
|
||||
(paragraph . org-e-ascii-paragraph)
|
||||
(plain-list . org-e-ascii-plain-list)
|
||||
(plain-text . org-e-ascii-plain-text)
|
||||
|
@ -1328,15 +1327,6 @@ INFO is a plist holding contextual information."
|
|||
(unless org-e-ascii-links-to-notes (format " (%s)" raw-link))))))))
|
||||
|
||||
|
||||
;;;; Macro
|
||||
|
||||
(defun org-e-ascii-macro (macro contents info)
|
||||
"Transcode a MACRO element from Org to ASCII.
|
||||
CONTENTS is nil. INFO is a plist holding contextual
|
||||
information."
|
||||
(org-export-expand-macro macro info))
|
||||
|
||||
|
||||
;;;; Paragraph
|
||||
|
||||
(defun org-e-ascii-paragraph (paragraph contents info)
|
||||
|
|
|
@ -76,7 +76,6 @@
|
|||
(groff-fragment . org-e-groff-groff-fragment)
|
||||
(line-break . org-e-groff-line-break)
|
||||
(link . org-e-groff-link)
|
||||
(macro . org-e-groff-macro)
|
||||
(paragraph . org-e-groff-paragraph)
|
||||
(plain-list . org-e-groff-plain-list)
|
||||
(plain-text . org-e-groff-plain-text)
|
||||
|
@ -1399,13 +1398,6 @@ INFO is a plist holding contextual information. See
|
|||
;; No path, only description. Try to do something useful.
|
||||
(t (format org-e-groff-link-with-unknown-path-format desc)))))
|
||||
|
||||
;;; Macro
|
||||
|
||||
(defun org-e-groff-macro (macro contents info)
|
||||
"Transcode a MACRO element from Org to Groff.
|
||||
CONTENTS is nil. INFO is a plist holding contextual information."
|
||||
;; Use available tools.
|
||||
(org-export-expand-macro macro info))
|
||||
|
||||
;;; Paragraph
|
||||
|
||||
|
|
|
@ -76,7 +76,6 @@
|
|||
(latex-fragment . org-e-html-latex-fragment)
|
||||
(line-break . org-e-html-line-break)
|
||||
(link . org-e-html-link)
|
||||
(macro . org-e-html-macro)
|
||||
(paragraph . org-e-html-paragraph)
|
||||
(plain-list . org-e-html-plain-list)
|
||||
(plain-text . org-e-html-plain-text)
|
||||
|
@ -2408,20 +2407,6 @@ INFO is a plist holding contextual information. See
|
|||
(t (format "<i>%s</i>" desc)))))
|
||||
|
||||
|
||||
;;;; Babel Call
|
||||
|
||||
;; Babel Calls are ignored.
|
||||
|
||||
|
||||
;;;; Macro
|
||||
|
||||
(defun org-e-html-macro (macro contents info)
|
||||
"Transcode a MACRO element from Org to HTML.
|
||||
CONTENTS is nil. INFO is a plist holding contextual information."
|
||||
;; Use available tools.
|
||||
(org-export-expand-macro macro info))
|
||||
|
||||
|
||||
;;;; Paragraph
|
||||
|
||||
(defun org-e-html-paragraph (paragraph contents info)
|
||||
|
|
|
@ -71,7 +71,6 @@
|
|||
(latex-fragment . org-e-latex-latex-fragment)
|
||||
(line-break . org-e-latex-line-break)
|
||||
(link . org-e-latex-link)
|
||||
(macro . org-e-latex-macro)
|
||||
(paragraph . org-e-latex-paragraph)
|
||||
(plain-list . org-e-latex-plain-list)
|
||||
(plain-text . org-e-latex-plain-text)
|
||||
|
@ -1820,15 +1819,6 @@ INFO is a plist holding contextual information. See
|
|||
(t (format org-e-latex-link-with-unknown-path-format desc)))))
|
||||
|
||||
|
||||
;;;; Macro
|
||||
|
||||
(defun org-e-latex-macro (macro contents info)
|
||||
"Transcode a MACRO element from Org to LaTeX.
|
||||
CONTENTS is nil. INFO is a plist holding contextual information."
|
||||
;; Use available tools.
|
||||
(org-export-expand-macro macro info))
|
||||
|
||||
|
||||
;;;; Paragraph
|
||||
|
||||
(defun org-e-latex-paragraph (paragraph contents info)
|
||||
|
|
|
@ -80,7 +80,6 @@
|
|||
(man-fragment . org-e-man-man-fragment)
|
||||
(line-break . org-e-man-line-break)
|
||||
(link . org-e-man-link)
|
||||
(macro . org-e-man-macro)
|
||||
(paragraph . org-e-man-paragraph)
|
||||
(plain-list . org-e-man-plain-list)
|
||||
(plain-text . org-e-man-plain-text)
|
||||
|
@ -745,15 +744,6 @@ INFO is a plist holding contextual information. See
|
|||
(t (format "\\fI%s\\fP" desc)))))
|
||||
|
||||
|
||||
;;;; Macro
|
||||
|
||||
(defun org-e-man-macro (macro contents info)
|
||||
"Transcode a MACRO element from Org to Man.
|
||||
CONTENTS is nil. INFO is a plist holding contextual information."
|
||||
;; Use available tools.
|
||||
(org-export-expand-macro macro info))
|
||||
|
||||
|
||||
;;;; Paragraph
|
||||
|
||||
(defun org-e-man-paragraph (paragraph contents info)
|
||||
|
|
|
@ -58,7 +58,6 @@
|
|||
(latex-fragment . org-e-odt-latex-fragment)
|
||||
(line-break . org-e-odt-line-break)
|
||||
(link . org-e-odt-link)
|
||||
(macro . org-e-odt-macro)
|
||||
(paragraph . org-e-odt-paragraph)
|
||||
(plain-list . org-e-odt-plain-list)
|
||||
(plain-text . org-e-odt-plain-text)
|
||||
|
@ -2606,20 +2605,6 @@ INFO is a plist holding contextual information. See
|
|||
"Emphasis" desc)))))
|
||||
|
||||
|
||||
;;;; Babel Call
|
||||
|
||||
;; Babel Calls are ignored.
|
||||
|
||||
|
||||
;;;; Macro
|
||||
|
||||
(defun org-e-odt-macro (macro contents info)
|
||||
"Transcode a MACRO element from Org to ODT.
|
||||
CONTENTS is nil. INFO is a plist holding contextual information."
|
||||
;; Use available tools.
|
||||
(org-export-expand-macro macro info))
|
||||
|
||||
|
||||
;;;; Paragraph
|
||||
|
||||
(defun org-e-odt-paragraph (paragraph contents info)
|
||||
|
|
|
@ -65,8 +65,7 @@
|
|||
;;; Define Back-End
|
||||
|
||||
(defvar org-e-texinfo-translate-alist
|
||||
'((babel-call . org-e-texinfo-babel-call)
|
||||
(bold . org-e-texinfo-bold)
|
||||
'((bold . org-e-texinfo-bold)
|
||||
(center-block . org-e-texinfo-center-block)
|
||||
(clock . org-e-texinfo-clock)
|
||||
(code . org-e-texinfo-code)
|
||||
|
@ -83,7 +82,6 @@
|
|||
(footnote-reference . org-e-texinfo-footnote-reference)
|
||||
(headline . org-e-texinfo-headline)
|
||||
(horizontal-rule . org-e-texinfo-horizontal-rule)
|
||||
(inline-babel-call . org-e-texinfo-inline-babel-call)
|
||||
(inline-src-block . org-e-texinfo-inline-src-block)
|
||||
(inlinetask . org-e-texinfo-inlinetask)
|
||||
(italic . org-e-texinfo-italic)
|
||||
|
@ -93,7 +91,6 @@
|
|||
(latex-fragment . org-e-texinfo-latex-fragment)
|
||||
(line-break . org-e-texinfo-line-break)
|
||||
(link . org-e-texinfo-link)
|
||||
(macro . org-e-texinfo-macro)
|
||||
(paragraph . org-e-texinfo-paragraph)
|
||||
(plain-list . org-e-texinfo-plain-list)
|
||||
(plain-text . org-e-texinfo-plain-text)
|
||||
|
@ -1277,13 +1274,6 @@ INFO is a plist holding contextual information. See
|
|||
;; No path, only description. Try to do something useful.
|
||||
(t (format org-e-texinfo-link-with-unknown-path-format desc)))))
|
||||
|
||||
;;; Macro
|
||||
|
||||
(defun org-e-texinfo-macro (macro contents info)
|
||||
"Transcode a MACRO element from Org to Texinfo.
|
||||
CONTENTS is nil. INFO is a plist holding contextual information."
|
||||
;; Use available tools.
|
||||
(org-export-expand-macro macro info))
|
||||
|
||||
;;; Menu
|
||||
|
||||
|
|
|
@ -178,8 +178,7 @@ All these properties should be back-end agnostic. Back-end
|
|||
specific properties are set through `org-export-define-backend'.
|
||||
Properties redefined there have precedence over these.")
|
||||
|
||||
(defconst org-export-special-keywords
|
||||
'("SETUP_FILE" "OPTIONS" "MACRO")
|
||||
(defconst org-export-special-keywords '("SETUP_FILE" "OPTIONS")
|
||||
"List of in-buffer keywords that require special treatment.
|
||||
These keywords are not directly associated to a property. The
|
||||
way they are handled must be hard-coded into
|
||||
|
@ -791,7 +790,6 @@ As an example, here is how the `e-ascii' back-end is defined:
|
|||
\(latex-fragment . org-e-ascii-latex-fragment)
|
||||
\(line-break . org-e-ascii-line-break)
|
||||
\(link . org-e-ascii-link)
|
||||
\(macro . org-e-ascii-macro)
|
||||
\(paragraph . org-e-ascii-paragraph)
|
||||
\(plain-list . org-e-ascii-plain-list)
|
||||
\(plain-text . org-e-ascii-plain-text)
|
||||
|
@ -1395,41 +1393,7 @@ Assume buffer is in Org mode. Narrowing, if any, is ignored."
|
|||
(org-export--get-inbuffer-options
|
||||
backend (cons file files))))))
|
||||
((string= key "OPTIONS")
|
||||
(org-export--parse-option-keyword val backend))
|
||||
((string= key "MACRO")
|
||||
(when (string-match
|
||||
"^\\([-a-zA-Z0-9_]+\\)\\(?:[ \t]+\\(.*?\\)[ \t]*$\\)?"
|
||||
val)
|
||||
(let ((key
|
||||
(intern
|
||||
(concat ":macro-"
|
||||
(downcase (match-string 1 val)))))
|
||||
(value (org-match-string-no-properties 2 val)))
|
||||
(cond
|
||||
((not value) nil)
|
||||
;; Value will be evaled: do not parse it.
|
||||
((string-match "\\`(eval\\>" value)
|
||||
(list key (list value)))
|
||||
;; Value has to be parsed for nested
|
||||
;; macros.
|
||||
(t
|
||||
(list
|
||||
key
|
||||
(let ((restr (org-element-restriction 'macro)))
|
||||
(org-element-parse-secondary-string
|
||||
;; If user explicitly asks for
|
||||
;; a newline, be sure to preserve it
|
||||
;; from further filling with
|
||||
;; `hard-newline'. Also replace
|
||||
;; "\\n" with "\n", "\\\n" with "\\n"
|
||||
;; and so on...
|
||||
(replace-regexp-in-string
|
||||
"\\(\\\\\\\\\\)n" "\\\\"
|
||||
(replace-regexp-in-string
|
||||
"\\(?:^\\|[^\\\\]\\)\\(\\\\n\\)"
|
||||
hard-newline value nil nil 1)
|
||||
nil nil 1)
|
||||
restr)))))))))))
|
||||
(org-export--parse-option-keyword val backend)))))
|
||||
(setq plist (org-combine-plists plist prop)))))))
|
||||
;; 2. Standard options, as in `org-export-options-alist'.
|
||||
(let* ((all (append org-export-options-alist
|
||||
|
@ -1530,22 +1494,7 @@ Assume buffer is in Org mode. Narrowing, if any, is ignored."
|
|||
(let* ((id (org-match-string-no-properties 1))
|
||||
(file (org-id-find-id-file id)))
|
||||
(when file (push (cons id (file-relative-name file)) alist)))))
|
||||
alist)
|
||||
:macro-modification-time
|
||||
(and visited-file
|
||||
(file-exists-p visited-file)
|
||||
(concat "(eval (format-time-string \"$1\" '"
|
||||
(prin1-to-string (nth 5 (file-attributes visited-file)))
|
||||
"))"))
|
||||
;; Store input file name as a macro.
|
||||
:macro-input-file (and visited-file (file-name-nondirectory visited-file))
|
||||
;; `:macro-date', `:macro-time' and `:macro-property' could as
|
||||
;; well be initialized as tree properties, since they don't
|
||||
;; depend on buffer properties. Though, it may be more logical
|
||||
;; to keep them close to other ":macro-" properties.
|
||||
:macro-date "(eval (format-time-string \"$1\"))"
|
||||
:macro-time "(eval (format-time-string \"$1\"))"
|
||||
:macro-property "(eval (org-entry-get nil \"$1\" 'selective))")))
|
||||
alist))))
|
||||
|
||||
(defun org-export--get-global-options (&optional backend)
|
||||
"Return global export options as a plist.
|
||||
|
@ -2497,8 +2446,8 @@ Return the updated communication channel."
|
|||
;;
|
||||
;; Note that `org-export-as' doesn't really parse the current buffer,
|
||||
;; but a copy of it (with the same buffer-local variables and
|
||||
;; visibility), where include keywords are expanded and Babel blocks
|
||||
;; are executed, if appropriate.
|
||||
;; visibility), where macros and include keywords are expanded and
|
||||
;; Babel blocks are executed, if appropriate.
|
||||
;; `org-export-with-current-buffer-copy' macro prepares that copy.
|
||||
;;
|
||||
;; File inclusion is taken care of by
|
||||
|
@ -2554,12 +2503,14 @@ Return code as a string."
|
|||
(let ((info (org-export-install-filters
|
||||
(org-export-get-environment backend subtreep ext-plist)))
|
||||
;; 2. Get parse tree. Buffer isn't parsed directly.
|
||||
;; Instead, a temporary copy is created, where include
|
||||
;; keywords are expanded and code blocks are evaluated.
|
||||
;; Instead, a temporary copy is created, where macros
|
||||
;; and include keywords are expanded and code blocks
|
||||
;; are evaluated.
|
||||
(tree (let ((buf (or (buffer-file-name (buffer-base-buffer))
|
||||
(current-buffer))))
|
||||
(org-export-with-current-buffer-copy
|
||||
(unless noexpand
|
||||
(org-macro-replace-all)
|
||||
(org-export-expand-include-keyword)
|
||||
;; TODO: Setting `org-current-export-file' is
|
||||
;; required by Org Babel to properly resolve
|
||||
|
@ -2891,7 +2842,7 @@ file should have."
|
|||
;; should be added here.
|
||||
;;
|
||||
;; As of now, functions operating on footnotes, headlines, links,
|
||||
;; macros, references, src-blocks, tables and tables of contents are
|
||||
;; references, src-blocks, tables and tables of contents are
|
||||
;; implemented.
|
||||
|
||||
;;;; For Affiliated Keywords
|
||||
|
@ -3360,35 +3311,6 @@ has type \"radio\"."
|
|||
info 'first-match)))
|
||||
|
||||
|
||||
;;;; For Macros
|
||||
;;
|
||||
;; `org-export-expand-macro' simply takes care of expanding macros.
|
||||
|
||||
(defun org-export-expand-macro (macro info)
|
||||
"Expand MACRO and return it as a string.
|
||||
INFO is a plist holding export options."
|
||||
(let* ((key (org-element-property :key macro))
|
||||
(args (org-element-property :args macro))
|
||||
;; User's macros are stored in the communication channel with
|
||||
;; a ":macro-" prefix. Replace arguments in VALUE. Also
|
||||
;; expand recursively macros within.
|
||||
(value (org-export-data
|
||||
(mapcar
|
||||
(lambda (obj)
|
||||
(if (not (stringp obj)) (org-export-data obj info)
|
||||
(replace-regexp-in-string
|
||||
"\\$[0-9]+"
|
||||
(lambda (arg)
|
||||
(nth (1- (string-to-number (substring arg 1))) args))
|
||||
obj)))
|
||||
(plist-get info (intern (format ":macro-%s" key))))
|
||||
info)))
|
||||
;; VALUE starts with "(eval": it is a s-exp, `eval' it.
|
||||
(when (string-match "\\`(eval\\>" value) (setq value (eval (read value))))
|
||||
;; Return string.
|
||||
(format "%s" (or value ""))))
|
||||
|
||||
|
||||
;;;; For References
|
||||
;;
|
||||
;; `org-export-get-ordinal' associates a sequence number to any object
|
||||
|
|
|
@ -974,78 +974,6 @@ Another text. (ref:text)
|
|||
info)))))
|
||||
|
||||
|
||||
|
||||
;;; Macro
|
||||
|
||||
(ert-deftest test-org-export/define-macro ()
|
||||
"Try defining various Org macro using in-buffer #+MACRO: keyword."
|
||||
;; Parsed macro.
|
||||
(should (equal (org-test-with-temp-text "#+MACRO: one 1"
|
||||
(org-export--get-inbuffer-options))
|
||||
'(:macro-one ("1"))))
|
||||
;; Evaled macro.
|
||||
(should (equal (org-test-with-temp-text "#+MACRO: two (eval (+ 1 1))"
|
||||
(org-export--get-inbuffer-options))
|
||||
'(:macro-two ("(eval (+ 1 1))"))))
|
||||
;; Incomplete macro.
|
||||
(should-not (org-test-with-temp-text "#+MACRO: three"
|
||||
(org-export--get-inbuffer-options)))
|
||||
;; Macro with newline character.
|
||||
(should (equal (org-test-with-temp-text "#+MACRO: four a\\nb"
|
||||
(org-export--get-inbuffer-options))
|
||||
'(:macro-four ("a\nb"))))
|
||||
;; Macro with protected newline character.
|
||||
(should (equal (org-test-with-temp-text "#+MACRO: five a\\\\nb"
|
||||
(org-export--get-inbuffer-options))
|
||||
'(:macro-five ("a\\nb"))))
|
||||
;; Recursive macro.
|
||||
(org-test-with-temp-text "#+MACRO: six 6\n#+MACRO: seven 1 + {{{six}}}"
|
||||
(should
|
||||
(equal
|
||||
(org-export--get-inbuffer-options)
|
||||
'(:macro-six
|
||||
("6")
|
||||
:macro-seven
|
||||
("1 + " (macro (:key "six" :value "{{{six}}}" :args nil :begin 5 :end 14
|
||||
:post-blank 0 :parent nil))))))))
|
||||
|
||||
(ert-deftest test-org-export/expand-macro ()
|
||||
"Test `org-export-expand-macro' specifications."
|
||||
;; Standard test.
|
||||
(should
|
||||
(equal
|
||||
"some text"
|
||||
(org-test-with-parsed-data "#+MACRO: macro some text\n{{{macro}}}"
|
||||
(org-export-expand-macro
|
||||
(org-element-map tree 'macro 'identity info t) info))))
|
||||
;; Macro with arguments.
|
||||
(should
|
||||
(equal
|
||||
"some text"
|
||||
(org-test-with-parsed-data "#+MACRO: macro $1 $2\n{{{macro(some,text)}}}"
|
||||
(org-export-expand-macro
|
||||
(org-element-map tree 'macro 'identity info t) info))))
|
||||
;; Macro with "eval"
|
||||
(should
|
||||
(equal
|
||||
"3"
|
||||
(org-test-with-parsed-data "#+MACRO: add (eval (+ $1 $2))\n{{{add(1,2)}}}"
|
||||
(org-export-expand-macro
|
||||
(org-element-map tree 'macro 'identity info t) info))))
|
||||
;; Nested macros.
|
||||
(should
|
||||
(equal
|
||||
"inner outer"
|
||||
(org-test-with-parsed-data
|
||||
"#+MACRO: in inner\n#+MACRO: out {{{in}}} outer\n{{{out}}}"
|
||||
(flet ((translate-macro (macro contents info)
|
||||
(org-export-expand-macro macro info)))
|
||||
(org-export-expand-macro
|
||||
(org-element-map tree 'macro 'identity info t)
|
||||
(org-combine-plists
|
||||
info `(:translate-alist ((macro . translate-macro))))))))))
|
||||
|
||||
|
||||
|
||||
;;; Src-block and example-block
|
||||
|
||||
|
|
Loading…
Reference in New Issue