summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <n.goaziou@gmail.com>2012-10-29 13:42:30 +0100
committerNicolas Goaziou <n.goaziou@gmail.com>2012-10-29 14:01:20 +0100
commita2120a9d7325a86f8ef459d2c4d7e3327e5a365d (patch)
tree8fa64d8ee2502455a071b3bc55b828efbdf9ffd6
parenta8c026cb26b7e2ed27d52e1637c3e219e163ec94 (diff)
downloadorg-mode-a2120a9d7325a86f8ef459d2c4d7e3327e5a365d.tar.gz
org-export: Expand correctly {{{title}}} and such
* contrib/lisp/org-export.el (org-export-as): Expand correctly {{{title}}} and such when they already contain a regular macro. This is done by expanding macros in two steps: at first regular macros, then document specific macros. (org-export-expand-macro): Remove function. * testing/lisp/test-org-export.el: Add test.
-rw-r--r--contrib/lisp/org-export.el116
-rw-r--r--testing/lisp/test-org-export.el36
2 files changed, 75 insertions, 77 deletions
diff --git a/contrib/lisp/org-export.el b/contrib/lisp/org-export.el
index 647518b..e9122f6 100644
--- a/contrib/lisp/org-export.el
+++ b/contrib/lisp/org-export.el
@@ -2563,49 +2563,65 @@ Return code as a string."
(goto-char (point-min))
(forward-line)
(narrow-to-region (point) (point-max))))
- ;; 1. Get export environment from original buffer. Also install
- ;; user's and developer's filters.
- (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 and macros are expanded and code blocks
- ;; are evaluated.
- (tree (org-export-with-current-buffer-copy
- (unless noexpand
- (org-export-expand-include-keyword)
- ;; Update radio targets since keyword
- ;; inclusion might have added some more.
- (org-update-radio-target-regexp)
- (org-export-expand-macro info)
- ;; TODO: Setting `org-current-export-file' is
- ;; required by Org Babel to properly resolve
- ;; noweb references. Once "org-exp.el" is
- ;; removed, modify
- ;; `org-export-blocks-preprocess' so it
- ;; accepts the value as an argument instead.
- (let ((org-current-export-file (current-buffer)))
- (org-export-blocks-preprocess)))
- (goto-char (point-min))
- ;; Run hook
- ;; `org-export-before-parsing-hook'. with current
- ;; back-end as argument.
- (run-hook-with-args
- 'org-export-before-parsing-hook backend)
- ;; Eventually parse buffer.
- (org-element-parse-buffer nil visible-only))))
- ;; 3. Call parse-tree filters to get the final tree.
- (setq tree
- (org-export-filter-apply-functions
- (plist-get info :filter-parse-tree) tree info))
- ;; 4. Now tree is complete, compute its properties and add
- ;; them to communication channel.
+ ;; Install user's and developer's filters in communication
+ ;; channel.
+ (let (info tree)
+ (org-export-with-current-buffer-copy
+ ;; Update communication channel and get parse tree. Buffer
+ ;; isn't parsed directly. Instead, a temporary copy is
+ ;; created, where include keywords, macros are expanded and
+ ;; code blocks are evaluated.
+ (unless noexpand
+ (org-export-expand-include-keyword)
+ ;; Update macro templates since #+INCLUDE keywords might
+ ;; have added some new ones.
+ (org-macro-initialize-templates)
+ (org-macro-replace-all org-macro-templates)
+ ;; TODO: Setting `org-current-export-file' is required by
+ ;; Org Babel to properly resolve noweb references. Once
+ ;; "org-exp.el" is removed, modify
+ ;; `org-export-blocks-preprocess' so it accepts the value
+ ;; as an argument instead.
+ (let ((org-current-export-file (current-buffer)))
+ (org-export-blocks-preprocess)))
+ ;; Update radio targets since keyword inclusion might have
+ ;; added some more.
+ (org-update-radio-target-regexp)
+ ;; Run hook `org-export-before-parsing-hook'. with current
+ ;; back-end as argument.
+ (goto-char (point-min))
+ (run-hook-with-args 'org-export-before-parsing-hook backend)
+ ;; Initialize communication channel.
+ (setq info
+ (org-export-install-filters
+ (org-export-get-environment backend subtreep ext-plist)))
+ ;; Expand export-specific set of macros: {{{author}}},
+ ;; {{{date}}}, {{{email}}} and {{{title}}}. It must be done
+ ;; once regular macros have been expanded, since document
+ ;; keywords may contain one of them.
+ (unless noexpand
+ (org-macro-replace-all
+ (list (cons "author"
+ (org-element-interpret-data (plist-get info :author)))
+ (cons "date"
+ (org-element-interpret-data (plist-get info :date)))
+ ;; EMAIL is not a parsed keyword: store it as-is.
+ (cons "email" (or (plist-get info :email) ""))
+ (cons "title"
+ (org-element-interpret-data (plist-get info :title))))))
+ ;; Eventually parse buffer. Call parse-tree filters to get
+ ;; the final tree.
+ (setq tree
+ (org-export-filter-apply-functions
+ (plist-get info :filter-parse-tree)
+ (org-element-parse-buffer nil visible-only) info)))
+ ;; Now tree is complete, compute its properties and add them
+ ;; to communication channel.
(setq info
(org-combine-plists
info (org-export-collect-tree-properties tree info)))
- ;; 5. Eventually transcode TREE. Wrap the resulting string
- ;; into a template, if required. Eventually call
- ;; final-output filter.
+ ;; Eventually transcode TREE. Wrap the resulting string into
+ ;; a template, if required. Finally call final-output filter.
(let* ((body (org-element-normalize-string (org-export-data tree info)))
(template (cdr (assq 'template
(plist-get info :translate-alist))))
@@ -2742,26 +2758,6 @@ Point is at buffer's beginning when BODY is applied."
(goto-char (point-min))
(progn ,@body))))))
-(defun org-export-expand-macro (info)
- "Expand every macro in buffer.
-INFO is a plist containing export options and buffer properties."
- ;; First update macro templates since #+INCLUDE keywords might have
- ;; added some new ones.
- (org-macro-initialize-templates)
- (org-macro-replace-all
- ;; Before expanding macros, install {{{author}}}, {{{date}}},
- ;; {{{email}}} and {{{title}}} templates.
- (nconc
- (list (cons "author"
- (org-element-interpret-data (plist-get info :author)))
- (cons "date"
- (org-element-interpret-data (plist-get info :date)))
- ;; EMAIL is not a parsed keyword: store it as-is.
- (cons "email" (or (plist-get info :email) ""))
- (cons "title"
- (org-element-interpret-data (plist-get info :title))))
- org-macro-templates)))
-
(defun org-export-expand-include-keyword (&optional included dir)
"Expand every include keyword in buffer.
Optional argument INCLUDED is a list of included file names along
diff --git a/testing/lisp/test-org-export.el b/testing/lisp/test-org-export.el
index 8b9f319..6fca839 100644
--- a/testing/lisp/test-org-export.el
+++ b/testing/lisp/test-org-export.el
@@ -439,13 +439,12 @@ body\n")))
"Test macro expansion in an Org buffer."
;; Standard macro expansion.
(should
- (equal "#+MACRO: macro1 value\nvalue"
+ (equal "#+MACRO: macro1 value\nvalue\n"
(org-test-with-temp-text "#+MACRO: macro1 value\n{{{macro1}}}"
- (let (info)
- (org-export-expand-macro info) (buffer-string)))))
- ;; Export specific macros.
+ (org-test-with-backend test (org-export-as 'test)))))
+ ;; Expand specific macros.
(should
- (equal "me 2012-03-29 me@here Title"
+ (equal "me 2012-03-29 me@here Title\n"
(org-test-with-temp-text
"
#+TITLE: Title
@@ -453,23 +452,26 @@ body\n")))
#+AUTHOR: me
#+EMAIL: me@here
{{{author}}} {{{date}}} {{{email}}} {{{title}}}"
- (let ((info (org-export-get-environment)))
- (org-export-expand-macro info)
- (goto-char (point-max))
- (buffer-substring (line-beginning-position)
- (line-end-position))))))
+ (let ((output (org-test-with-backend test (org-export-as 'test))))
+ (substring output (string-match ".*\n\\'" output))))))
+ ;; Expand specific macros when property contained a regular macro
+ ;; already.
+ (should
+ (equal "value\n"
+ (org-test-with-temp-text "
+#+MACRO: macro1 value
+#+TITLE: {{{macro1}}}
+{{{title}}}"
+ (let ((output (org-test-with-backend test (org-export-as 'test))))
+ (substring output (string-match ".*\n\\'" output))))))
;; Expand macros with templates in included files.
(should
- (equal "success"
+ (equal "success\n"
(org-test-with-temp-text
(format "#+INCLUDE: \"%s/examples/macro-templates.org\"
{{{included-macro}}}" org-test-dir)
- (let (info)
- (org-export-expand-include-keyword)
- (org-export-expand-macro info)
- (goto-char (point-max))
- (buffer-substring (line-beginning-position)
- (line-end-position)))))))
+ (let ((output (org-test-with-backend test (org-export-as 'test))))
+ (substring output (string-match ".*\n\\'" output)))))))
(ert-deftest test-org-export/user-ignore-list ()
"Test if `:ignore-list' accepts user input."