1

I have an org file with the following contents:

#+begin_src python
from datetime import datetime
return datetime.now()
#+end_src

#+RESULTS:
: 2021-10-30 17:05:27.247133

I want to export this file to HTML, both code and output. This can be achieved if I just add :exports both to the code header. But the tricky part is:

  1. The org-mode exporter just evaluates the code, gets the new result (instead of the result shown in my org file), and converts it to HTML. The new output is not what I want because it runs in a new context. I want the output shown in the HTML to be exactly the same as the shown in the file.
  2. If the code doesn't have a #+RESULTS: part in the org file, don't show it in the generated HTML file as well.
  3. I have a lot of such org files to be converted into HTML, so it would be really great if I can change the behavior by just modifying some variables instead of changing each code block one by one.

Is it possible?

1 Answer 1

1

You can use the eval header to influence when/how to evaluate a code block (do C-h i g(org)Evaluating Code Blocks and scroll down to the Limit code block evaluation subsection to see the details). In your case you want :eval never-export, which is described as follows in the manual:

Org does not evaluate the source code when exporting, yet the user can evaluate it interactively.

You can specify it per-code-block with:

#+begin_src python :eval never-export
...
#+end_src

You can specify it per-subtree with:

* Limit it to the current subtree
  :PROPERTIES:
  :header-args: :eval never-export

or you can specify it per-file with:

#+PROPERTY: header-args :eval never-export

You can also limit it to blocks for a specified language by using e.g. header-args:python instead of header-args.

I looked for an option that you can set globally, but I don't think one exists. The closest I found is org-export-use-babel: setting it to nil stops the evaluation of (all) source blocks, but unfortunately it's a bit too blunt for your purposes: it also ignores headers. So I think you'll have to be satisfied with the per-file method. If you can identify all the files of interest, you could do a batch edit of all of them to add the appropriate #+PROPERTY: line at the top of each. Better yet, you might want to add a #+SETUPFILE: line in the batch edit instead, e.g.:

#+SETUPFILE: ~/src/org/setup.org

and put the #+PROPERTY: line in the setup file. That would be a one-time operation and from then on every file that includes that line would get whatever settings you put in your setup file - and if at some point you wanted to get rid of these customizations, you could make the setup file empty - or even delete it altogether, although that generates complaints in the *Messages* buffer.

EDIT: Here's how I tested. I created an Org mode file like this:

#+SETUPFILE: ~/src/org/setup.org


* Test

#+begin_src elisp
(random)
#+end_src


#+begin_src python :results value
from random import random
return random()
#+end_src

#+RESULTS:
: 0.10363433247781972


with the setup file containing this:

#+PROPERTY: header-args :exports both :eval never-export

and exported it to HTML. The resulting HTML file shows this (cut and pasted directly from Firefox):



1. Test

(random)

from random import random
return random()

0.10363433247781972

so no result from the lisp code block and the same result from the python code block as in the Org mode file (i.e. the RNG was not exercised again, the code block was not evaluated on export). I then evaluated the lisp code block manually to get this buffer:

#+SETUPFILE: ~/src/org/setup.org


* Test

#+begin_src elisp
(random)
#+end_src

#+RESULTS:
: 1890415366607963977


#+begin_src python :results value
from random import random
return random()
#+end_src

#+RESULTS:
: 0.10363433247781972

I saved the buffer and exported again to get this in Firefox:


1. Test

(random)

1890415366607963977

from random import random
return random()

0.10363433247781972

The resulting HTML contains exactly the same results as the Org mode file does: the code blocks do not get reevaluated. It seems to me that that's exactly what you asked for.

And a couple of things that you might have missed:

  • Make sure that the :exports both header is present.
  • Make sure that you save the buffer in the file before exporting.
  • Make sure that if you add #+PROPERTY: or #+SETUPFILE: lines in the buffer, you restart Org mode on the buffer by pressing C-c C-c on one of those lines (any keyword line will do, actually).
3
  • Thanks, that's really helpful, but it doesn't solve all of my problems. Maybe I'm not clear enough in my original post. I said that I want the output shown in the HTML to be exactly the same as the org file, which means I want the code along with the result evaluated in my org file to be shown in the HTML. In other words, the result should not be evaluated every time the file is converted, the result should be taken directly from the org file. If the org file doesn't contain the #+RESULS: part, then don't show it in the HTML file, either. Is there any way to do that?
    – Searene
    Oct 31, 2021 at 12:44
  • Have you tried it? Did you keep the :exports both (if not, you should)? In my experiments, that's exactly what happens.
    – NickD
    Oct 31, 2021 at 13:32
  • 1
    Yes, it worked after adding :exports both, thanks!
    – Searene
    Oct 31, 2021 at 15:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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