* org-export-current-backend variable and org-mode 8 @ 2013-07-31 16:27 Christophe Rhodes 2013-07-31 18:41 ` Brett Viren 0 siblings, 1 reply; 9+ messages in thread From: Christophe Rhodes @ 2013-07-31 16:27 UTC (permalink / raw) To: emacs-orgmode Hi, In org-mode 7, I was able to use the (documented) variable org-export-current-backend to test what the current backend is, allowing me to dynamically produce and include images of different formats depending on whether I was exporting to latex (tikz) or html (png). In org-mode 8, I cannot find this variable, or any documented variable of a similar nature. What is the recommended way for dispatching at the emacs-lisp level when exporting a document on the export backend? Thanks, Christophe ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: org-export-current-backend variable and org-mode 8 2013-07-31 16:27 org-export-current-backend variable and org-mode 8 Christophe Rhodes @ 2013-07-31 18:41 ` Brett Viren 2013-07-31 19:09 ` Christophe Rhodes 0 siblings, 1 reply; 9+ messages in thread From: Brett Viren @ 2013-07-31 18:41 UTC (permalink / raw) To: Christophe Rhodes; +Cc: emacs-orgmode [-- Attachment #1: Type: text/plain, Size: 1333 bytes --] Hi Christophe, Christophe Rhodes <csr21@cantab.net> writes: > In org-mode 7, I was able to use the (documented) variable > org-export-current-backend to test what the current backend is, allowing > me to dynamically produce and include images of different formats > depending on whether I was exporting to latex (tikz) or html (png). > > In org-mode 8, I cannot find this variable, or any documented variable > of a similar nature. What is the recommended way for dispatching at the > emacs-lisp level when exporting a document on the export backend? I don't know if this is exactly what you are asking for but I hit on the following a few weeks ago. It defines an elisp macro inside the org file and then calls it later in the header of a code block to switch the output file names based on which backend (if any) is in effect. I hope it helps. If you have a better way to do these kind of output switches, I'd like to know. * COMMENT setup #+begin_src emacs-lisp :results silent (defmacro by-backend (&rest body) `(case (if (boundp 'backend) backend nil) ,@body)) #+end_src * A graph #+header: :file (by-backend (html "graph.png") (latex "graph.pdf") (t "graph.svg")) #+header: :export results #+begin_src dot digraph Name { tail -> head; } #+end_src -Brett. [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: org-export-current-backend variable and org-mode 8 2013-07-31 18:41 ` Brett Viren @ 2013-07-31 19:09 ` Christophe Rhodes 2013-07-31 20:40 ` Nicolas Goaziou 0 siblings, 1 reply; 9+ messages in thread From: Christophe Rhodes @ 2013-07-31 19:09 UTC (permalink / raw) To: emacs-orgmode [-- Attachment #1: Type: text/plain, Size: 2158 bytes --] Brett Viren <bv@bnl.gov> writes: > Christophe Rhodes <csr21@cantab.net> writes: > >> In org-mode 7, I was able to use the (documented) variable >> org-export-current-backend to test what the current backend is, allowing >> me to dynamically produce and include images of different formats >> depending on whether I was exporting to latex (tikz) or html (png). >> >> In org-mode 8, I cannot find this variable, or any documented variable >> of a similar nature. What is the recommended way for dispatching at the >> emacs-lisp level when exporting a document on the export backend? > > I don't know if this is exactly what you are asking for but I hit on the > following a few weeks ago. It defines an elisp macro inside the org > file and then calls it later in the header of a code block to switch the > output file names based on which backend (if any) is in effect. I hope > it helps. Thanks. Well, it proves at least that I'm not going mad :-( > If you have a better way to do these kind of output switches, I'd like > to know. > #+begin_src emacs-lisp :results silent > (defmacro by-backend (&rest body) > `(case (if (boundp 'backend) backend nil) ,@body)) > #+end_src It's funny -- I felt queasy using the bare backend variable in the olden 6.x days, and was very happy when org-export-current-backend showed up. Now, there's a real reason to be worried about using backend: it's fairly clearly used as an internal variable, and all it would take would be for lexical binding to be turned on for ox.el and this would (probably) stop working. If we're grubbing around in internals, I might be tempted instead by something like [untested] #+begin_src emacs-lisp :exports results :results silent (unless (boundp 'org-export-current-backend) (defadvice org-export-as (around oecb-around) (let ((org-export-current-backend (ad-get-arg 0))) ad-do-it))) #+end_src so that if (as I hope) org-export-current-backend makes a later reappearance, my documents can work with both org-mode 7 and 8, and maybe 9? I'm hoping that the disappearance of the variable is an oversight rather than intentional :-/ Cheers, Christophe [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: org-export-current-backend variable and org-mode 8 2013-07-31 19:09 ` Christophe Rhodes @ 2013-07-31 20:40 ` Nicolas Goaziou 2013-07-31 21:21 ` Christophe Rhodes 0 siblings, 1 reply; 9+ messages in thread From: Nicolas Goaziou @ 2013-07-31 20:40 UTC (permalink / raw) To: Christophe Rhodes; +Cc: emacs-orgmode Hello, Christophe Rhodes <csr21@cantab.net> writes: > so that if (as I hope) org-export-current-backend makes a later > reappearance, my documents can work with both org-mode 7 and 8, and > maybe 9? I'm hoping that the disappearance of the variable is an > oversight rather than intentional :-/ It is intentional. I tried to reduce the number of dynamically scoped variables. On the other hand, hooks and filters all get back-end's name, if any, as an argument, which limits the need for that variable. The only missing part is Babel. I thought the recently introduced `by-backend' feature was sufficient. Isn't it the case? I also thought about reintroducing `org-export-current-backend', but that would be redundant with hooks and filters' arguments. Removing these is not an option either, as that would break every hook/filter in the wild. Regards, -- Nicolas Goaziou ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: org-export-current-backend variable and org-mode 8 2013-07-31 20:40 ` Nicolas Goaziou @ 2013-07-31 21:21 ` Christophe Rhodes 2013-08-02 10:01 ` Christophe Rhodes 0 siblings, 1 reply; 9+ messages in thread From: Christophe Rhodes @ 2013-07-31 21:21 UTC (permalink / raw) To: emacs-orgmode Nicolas Goaziou <n.goaziou@gmail.com> writes: > Christophe Rhodes <csr21@cantab.net> writes: > >> so that if (as I hope) org-export-current-backend makes a later >> reappearance, my documents can work with both org-mode 7 and 8, and >> maybe 9? I'm hoping that the disappearance of the variable is an >> oversight rather than intentional :-/ > > It is intentional. I tried to reduce the number of dynamically scoped > variables. > > On the other hand, hooks and filters all get back-end's name, if any, as > an argument, which limits the need for that variable. The only missing > part is Babel. I thought the recently introduced `by-backend' feature > was sufficient. Isn't it the case? The `by-backend' macro in Brett Viren's message upthread? Personally I don't consider that sufficient, because it feels very fragile: a simple renaming of org-mode internal variables, or turning on lexical binding, and the macro will no longer work. (If you mean some other `by-backend', I haven't seen it). In particular, I would like to have some kind of confidence that documents that I wrote last year will still be exportable next year with only minor modifications necessary, and to do that I think I need to convince you that this is valuable, enough that you are willing to commit to some stable way of accessing the information previously held in org-export-current-backend. > I also thought about reintroducing `org-export-current-backend', but > that would be redundant with hooks and filters' arguments. Removing > these is not an option either, as that would break every hook/filter in > the wild. Please don't remove hooks and filters, or change their arguments! But please consider reintroducing org-export-current-backend; I have just checked, and the document that I am currently editing exports to latex and html unmodified from the org-mode 7 version, apart from some trivial variable renamings in the elisp setup and the reintroduction through advice of org-export-current-backend. And although that's fairly straightforward for me to achieve, it's a cost, and one that I have to pay every time I want to share a reproducible research document with a colleague who hasn't upgraded to org-mode 8 yet, maybe because some of /their/ documents don't yet build under org-mode 8... Best wishes, Christophe ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: org-export-current-backend variable and org-mode 8 2013-07-31 21:21 ` Christophe Rhodes @ 2013-08-02 10:01 ` Christophe Rhodes 2013-08-03 7:50 ` Nicolas Goaziou 0 siblings, 1 reply; 9+ messages in thread From: Christophe Rhodes @ 2013-08-02 10:01 UTC (permalink / raw) To: emacs-orgmode [-- Attachment #1: Type: text/plain, Size: 1140 bytes --] Christophe Rhodes <csr21@cantab.net> writes: > The `by-backend' macro in Brett Viren's message upthread? Personally I > don't consider that sufficient, because it feels very fragile: a simple > renaming of org-mode internal variables, or turning on lexical binding, > and the macro will no longer work. (If you mean some other > `by-backend', I haven't seen it). > > In particular, I would like to have some kind of confidence that > documents that I wrote last year will still be exportable next year with > only minor modifications necessary, and to do that I think I need to > convince you that this is valuable, enough that you are willing to > commit to some stable way of accessing the information previously held > in org-export-current-backend. Attempting to put my money where my mouth is: find attached a patch to restore org-export-current-backend. I think this is a TINYCHANGE despite the large diff -- it's almost all whitespace, and the docstring is restored verbatim from org-mode 7.9 (I haven't updated it for the removal of the docbook backend, for example, primarily so that it has minimal novel information in it). [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-ox-restore-org-export-current-backend-variable.patch --] [-- Type: text/x-diff, Size: 10636 bytes --] From 29d11fdda3b8302d437fdb309c195aa9e806505d Mon Sep 17 00:00:00 2001 From: Christophe Rhodes <c.rhodes@gold.ac.uk> Date: Fri, 2 Aug 2013 10:56:37 +0100 Subject: [PATCH] ox: restore org-export-current-backend variable * lisp/ox.el (org-export-current-backend): new variable. (org-export-as): bind it. TINYCHANGE --- lisp/ox.el | 214 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 111 insertions(+), 103 deletions(-) diff --git a/lisp/ox.el b/lisp/ox.el index 5d28a81..8962428 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -290,6 +290,13 @@ and its CDR is a list of export options.") This marker will be used with `C-u C-c C-e' to make sure export repetition uses the same subtree if the previous command was restricted to a subtree.") +(defvar org-export-current-backend nil + "During export, this will be bound to a symbol such as 'html, + 'latex, 'docbook, 'ascii, etc, indicating which of the export + backends is in use. Otherwise it has the value nil. Users + should not attempt to change the value of this variable + directly, but it can be used in code to test whether export is + in progress, and if so, what the backend is.") \f ;;; User-configurable Variables ;; @@ -2947,109 +2954,110 @@ still inferior to file-local settings. Return code as a string." (when (symbolp backend) (setq backend (org-export-get-backend backend))) (org-export-barf-if-invalid-backend backend) - (save-excursion - (save-restriction - ;; Narrow buffer to an appropriate region or subtree for - ;; parsing. If parsing subtree, be sure to remove main headline - ;; too. - (cond ((org-region-active-p) - (narrow-to-region (region-beginning) (region-end))) - (subtreep - (org-narrow-to-subtree) - (goto-char (point-min)) - (forward-line) - (narrow-to-region (point) (point-max)))) - ;; Initialize communication channel with original buffer - ;; attributes, unavailable in its copy. - (let* ((info (org-combine-plists - (list :export-options - (delq nil - (list (and subtreep 'subtree) - (and visible-only 'visible-only) - (and body-only 'body-only)))) - (org-export--get-buffer-attributes))) - tree) - ;; Store default title in `org-export--default-title' so that - ;; `org-export-get-environment' can access it from buffer's - ;; copy and then add it properly to communication channel. - (org-export-store-default-title) - ;; 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. - (org-export-with-buffer-copy - ;; Run first hook with current back-end's name as argument. - (run-hook-with-args 'org-export-before-processing-hook - (org-export-backend-name backend)) - (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) - (org-export-execute-babel-code) - ;; Update radio targets since keyword inclusion might have - ;; added some more. - (org-update-radio-target-regexp) - ;; Run last hook with current back-end's name as argument. - (goto-char (point-min)) - (save-excursion - (run-hook-with-args 'org-export-before-parsing-hook - (org-export-backend-name backend))) - ;; Update communication channel with environment. Also - ;; install user's and developer's filters. - (setq info - (org-export-install-filters - (org-combine-plists - info (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. - (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))))) - ;; Call options filters and update export options. We do not - ;; use `org-export-filter-apply-functions' here since the - ;; arity of such filters is different. - (let ((backend-name (org-export-backend-name backend))) - (dolist (filter (plist-get info :filter-options)) - (let ((result (funcall filter info backend-name))) - (when result (setq info result))))) - ;; Parse buffer and call parse-tree filter on it. - (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))) - ;; Eventually transcode TREE. Wrap the resulting string into - ;; a template. - (let* ((body (org-element-normalize-string - (or (org-export-data tree info) ""))) - (inner-template (cdr (assq 'inner-template - (plist-get info :translate-alist)))) - (full-body (if (not (functionp inner-template)) body - (funcall inner-template body info))) - (template (cdr (assq 'template - (plist-get info :translate-alist))))) - ;; Remove all text properties since they cannot be - ;; retrieved from an external process. Finally call - ;; final-output filter and return result. - (org-no-properties - (org-export-filter-apply-functions - (plist-get info :filter-final-output) - (if (or (not (functionp template)) body-only) full-body - (funcall template full-body info)) - info)))))))) + (let ((org-export-current-backend backend)) + (save-excursion + (save-restriction + ;; Narrow buffer to an appropriate region or subtree for + ;; parsing. If parsing subtree, be sure to remove main headline + ;; too. + (cond ((org-region-active-p) + (narrow-to-region (region-beginning) (region-end))) + (subtreep + (org-narrow-to-subtree) + (goto-char (point-min)) + (forward-line) + (narrow-to-region (point) (point-max)))) + ;; Initialize communication channel with original buffer + ;; attributes, unavailable in its copy. + (let* ((info (org-combine-plists + (list :export-options + (delq nil + (list (and subtreep 'subtree) + (and visible-only 'visible-only) + (and body-only 'body-only)))) + (org-export--get-buffer-attributes))) + tree) + ;; Store default title in `org-export--default-title' so that + ;; `org-export-get-environment' can access it from buffer's + ;; copy and then add it properly to communication channel. + (org-export-store-default-title) + ;; 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. + (org-export-with-buffer-copy + ;; Run first hook with current back-end's name as argument. + (run-hook-with-args 'org-export-before-processing-hook + (org-export-backend-name backend)) + (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) + (org-export-execute-babel-code) + ;; Update radio targets since keyword inclusion might have + ;; added some more. + (org-update-radio-target-regexp) + ;; Run last hook with current back-end's name as argument. + (goto-char (point-min)) + (save-excursion + (run-hook-with-args 'org-export-before-parsing-hook + (org-export-backend-name backend))) + ;; Update communication channel with environment. Also + ;; install user's and developer's filters. + (setq info + (org-export-install-filters + (org-combine-plists + info (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. + (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))))) + ;; Call options filters and update export options. We do not + ;; use `org-export-filter-apply-functions' here since the + ;; arity of such filters is different. + (let ((backend-name (org-export-backend-name backend))) + (dolist (filter (plist-get info :filter-options)) + (let ((result (funcall filter info backend-name))) + (when result (setq info result))))) + ;; Parse buffer and call parse-tree filter on it. + (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))) + ;; Eventually transcode TREE. Wrap the resulting string into + ;; a template. + (let* ((body (org-element-normalize-string + (or (org-export-data tree info) ""))) + (inner-template (cdr (assq 'inner-template + (plist-get info :translate-alist)))) + (full-body (if (not (functionp inner-template)) body + (funcall inner-template body info))) + (template (cdr (assq 'template + (plist-get info :translate-alist))))) + ;; Remove all text properties since they cannot be + ;; retrieved from an external process. Finally call + ;; final-output filter and return result. + (org-no-properties + (org-export-filter-apply-functions + (plist-get info :filter-final-output) + (if (or (not (functionp template)) body-only) full-body + (funcall template full-body info)) + info))))))))) ;;;###autoload (defun org-export-to-buffer -- 1.7.10.4 [-- Attachment #3: Type: text/plain, Size: 26 bytes --] Best wishes, Christophe ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: org-export-current-backend variable and org-mode 8 2013-08-02 10:01 ` Christophe Rhodes @ 2013-08-03 7:50 ` Nicolas Goaziou 2013-08-03 17:55 ` Achim Gratz 0 siblings, 1 reply; 9+ messages in thread From: Nicolas Goaziou @ 2013-08-03 7:50 UTC (permalink / raw) To: Christophe Rhodes; +Cc: emacs-orgmode Hello, Christophe Rhodes <csr21@cantab.net> writes: >> The `by-backend' macro in Brett Viren's message upthread? Personally I >> don't consider that sufficient, because it feels very fragile: a simple >> renaming of org-mode internal variables, or turning on lexical binding, >> and the macro will no longer work. (If you mean some other >> `by-backend', I haven't seen it). I thought `by-backend' was in core already. Anyway, if it is, we'll make sure it will not be fragile anymore. > Subject: [PATCH] ox: restore org-export-current-backend variable > > * lisp/ox.el (org-export-current-backend): new variable. > (org-export-as): bind it. Applied a slightly different version. Thank you. Regards, -- Nicolas Goaziou ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: org-export-current-backend variable and org-mode 8 2013-08-03 7:50 ` Nicolas Goaziou @ 2013-08-03 17:55 ` Achim Gratz 2013-08-03 19:08 ` Nicolas Goaziou 0 siblings, 1 reply; 9+ messages in thread From: Achim Gratz @ 2013-08-03 17:55 UTC (permalink / raw) To: emacs-orgmode Nicolas Goaziou writes: > Applied a slightly different version. Thank you. Shouldn't d1d918100e be in maint? Also, I don't think that "nil" should mean both "export in progress with an anonymous backend" and "no export in progress". You've been advertising the use of anonmous derived backends to customize exporting, so to me it would make more sense if somehow there was a way to detect that situation and then get the name of the parent backend instead. Regards, Achim. -- +<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+ Factory and User Sound Singles for Waldorf rackAttack: http://Synth.Stromeko.net/Downloads.html#WaldorfSounds ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: org-export-current-backend variable and org-mode 8 2013-08-03 17:55 ` Achim Gratz @ 2013-08-03 19:08 ` Nicolas Goaziou 0 siblings, 0 replies; 9+ messages in thread From: Nicolas Goaziou @ 2013-08-03 19:08 UTC (permalink / raw) To: Achim Gratz; +Cc: emacs-orgmode Hello, Achim Gratz <Stromeko@nexgo.de> writes: > Nicolas Goaziou writes: >> Applied a slightly different version. Thank you. > > Shouldn't d1d918100e be in maint? No. Back-end as defstructs is only in the "master" branch. > Also, I don't think that "nil" should mean both "export in progress with > an anonymous backend" and "no export in progress". You've been > advertising the use of anonmous derived backends to customize exporting, > so to me it would make more sense if somehow there was a way to detect > that situation and then get the name of the parent backend instead. A back-end, anonymous or not, may have no parent at all. We can also store the full back-end object instead of its name. In this case, an unnamed back-end is not the same as nil. Alas, this variable was introduced for compatibility, which that solution kinda defeats. Speaking about compatibility, previous export framework didn't have anonymous back-ends. Handling the "nil" case would give us nothing more. Regards, -- Nicolas Goaziou ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2013-08-03 19:08 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-07-31 16:27 org-export-current-backend variable and org-mode 8 Christophe Rhodes 2013-07-31 18:41 ` Brett Viren 2013-07-31 19:09 ` Christophe Rhodes 2013-07-31 20:40 ` Nicolas Goaziou 2013-07-31 21:21 ` Christophe Rhodes 2013-08-02 10:01 ` Christophe Rhodes 2013-08-03 7:50 ` Nicolas Goaziou 2013-08-03 17:55 ` Achim Gratz 2013-08-03 19:08 ` Nicolas Goaziou
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).