1

Here is an org document

#+title: my document
#+options: num:nil

* first section
** first subsection
* second section

My problem is that I want the option #+option: num:nil to only be applied when I export to html. When I export to other formats, I do not want this option applied. Is this possible?

3
  • Doess this help? – NickD Mar 22 at 0:48
  • @NickD Rather than do something fancy with multiple files and have to adjust the file for each export, I'd rather just comment/uncomment the option with each export. To me, a solution would be something that works for every export without my intervention. I'm kind of surprised there is a syntax like #+option_html for situations like this! – Brian Fitzpatrick Mar 22 at 1:53
  • Isn't that what this answer is supposed to do? (BTW, I have not tested it - I'm taking the author's assurance that it worked for him at face value). Granted, it's not as simple as having explicit #+OPTION_HTML syntax, but the latter is a moving target for Org-mode: every time somebody adds an exporter, the syntax of Org mode would have to change. – NickD Mar 22 at 2:18
0

Here's a better answer than the one linked in the comments: you can evaluate arbitrary Lisp code in a macro:

#+MACRO: foo (eval <lisp code...>)

When the macro is expanded, the code is executed. So we can do something like this:

#+MACRO: options (eval (if (org-org-export-derived-backend-p org-export-current-backend 'html) "#+OPTIONS: num:nil"))

{{{options}}}

#+title: my document

* first section
** first subsection
* second section

org-export-current-backend is a dynamically scoped variable that is set by the exporter before it touches the document. Now when this document is exported, the macro is defined and it is then expanded (through the {{{options}}} macro call). The Lisp expression is evaluated and if the current backend is (or is derived from) the HTML backend, then the `#+OPTIONS: num:nil' string is the result of the evaluation - and the expansion of the macro. Since macros are expanded as the first step in the export process, the rest of the export proceeds as if the options string was already included in the file.

Here is an elaboration of the idea above to work around the fact (AFAIK) that the macro definition needs to be in a single line. Define a Lisp function to do what you want (which may be arbitrarily complicated) and then eval the call to the function in the macro definition:

#+MACRO: options (eval (ndk/options org-export-current-backend))
{{{options}}}

* foo
This is foo

** foo.2
This is foo.2
* bar
This is bar
* baz
This is baz

* Code                                                                  :noexport:

#+begin_src elisp
  (defun ndk/options (be)
     "Different options for different backends. Caveat: this function needs to be
      defined, before the file is exported. And if e.g. an option changes, it needs to
      be defined again (just run the code block with `C-c C-c')."
     (cond
      ((org-export-derived-backend-p be 'latex) "#+OPTIONS: latex:t num:t toc:nil")
      ((org-export-derived-backend-p be 'html) "#+OPTIONS: html:t num:nil toc:t")))
#+end_src

That works OK interactively, but not in batch mode: you'd have to store the definition of the function in some file and then use emacs --batch -l file.el .... to load it, so that it can be used.

But that can be done by giving the code block a name and using the org-sbe function to do the evaluation of the code block. We can then incorporate that into the definition of the macro, so that when it is expanded, it first evaluates the code block and then it calls the function to produce the options:

#+MACRO: options (eval (progn (org-sbe "ndk/options") (ndk/options org-export-current-backend)))

{{{options}}}

... as before ...

* Code                                                                  :noexport:

#+name: ndk/options
#+begin_src elisp
    ... as before ...
#+end_src

You can now go wild in the function - nothing else needs to be touched.

I'm pretty sure that you can have multiple #+OPTIONS lines, so you can hardwire the options that you want for every backend and just use the function for the backend-dependent options only:

#+MACRO: ....
#+OPTIONS: ... backend-independent options go here ...
{{{options}}}

...

Moreover, later #+OPTIONS lines override earlier ones, so you have defaults defined in the first #+OPTIONS line and override them for specific backends using the (macro expanded) second #+OPTIONS line.

The main idea was presented by Juan Manuel Macías on the Org mode mailing list - see this post and its enclosing thread.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.