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:
Nicolas Goaziou 2012-09-01 00:03:04 +02:00
parent 4a2f3c2093
commit ea77b2ccb2
9 changed files with 11 additions and 239 deletions

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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