Macros
You can evaluate arbitrary Lisp code using a macro:
#+MACRO: macroname (eval <lisp code...>)
When the macro is expanded, the code is executed.
Using the Macro
So we can do something like this:
#+MACRO: options (eval (if (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.
Including lisp functions
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 would have to store the definition of the function in some file and then use emacs --batch -l file.el ....
to load it.
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.
Conclusion
With multiple #+OPTIONS
lines,
you can set defaults for every backend
and use the macro to override only backend-dependent options
(later #+OPTIONS
lines override earlier ones):
#+MACRO: ....
#+OPTIONS: ... backend-independent options go here ...
{{{options}}}
...
The main idea was presented by Juan Manuel Macías on the Org mode mailing list - see this post and its enclosing thread.
#+option_html
for situations like this!