chasberry / orgmode-accessories

Add ons for orgmode
78 stars 18 forks source link

export of code blocks not working #11

Closed tagteam closed 7 years ago

tagteam commented 7 years ago

Hi, thanks a lot for making ox-ravel. this is just what I need for teaching R-studio users. however, I am struggling to get ox-ravel to export the R-code, that is header argument :exports code is ignored. it seems that this only happens when header argument :eval never-export is also present. but, the other exporters (html, beamer, odt, etc) work in both cases (with and without :eval never-export).

I would love to edebug this myself but do not understand enough orgmode plus9 export philosophy. any hint/help is very much appreciated!

chasberry commented 7 years ago

You want the code to be shown, but not executed, right?

ox-ravel will export any code for which the :exports header is code, results, or both.

It is up to the author to build in the right chunk options. Look at slidify-example.org and you will see the slides under Mauna Whau Plot - code and Mauna Whau Plot - Displayed to get an idea how this might work.

If you are using one of the knitr family of engines (which Rstudio does IIUC), having

#+ATTR_RAVEL: eval=FALSE

just before the src block, or :ravel eval=FALSE as a header is usually enough.

If you have set echo=FALSE as a global chunk option, then you need to set it to TRUE for the chunk you want to display, i.e.

#+ATTR_RAVEL: eval=FALSE, echo=TRUE before the src block or :ravel eval=FALSE,echo=TRUE as a header arg.

It is a long story, but src block headers do not map to chunk options in a one-to-one fashion although the code --> eval=FALSE,echo=TRUE seems like an obvious mapping. I have an open issue to implement some mapping features, but it hasn't been a priority.

If this doesn't solve your issue, please post a minimal reproducible example and including commands in R to process the *.Rmd.

tagteam commented 7 years ago

thanks for the quick reply! it does not solve my issue because I want to export the document to both html and Rmd. my life in orgmode has improved so much ever since I separated the process of block evaluation from the process of exporting the document, that I would rather not go back and set :eval yes. so, here is a minimal orgmode file with R

+BEGIN_SRC R :exports code :eval never-export :ravel eval=FALSE

bla <- 1 bla

+END_SRC

+RESULTS:

: 1

In the exported html file I have bla <- 1 and bla but in the expored Rmd file I only have '1'. setting :eval yes removes the issue.

chasberry commented 7 years ago

If your motivation for :eval never-export is to prevent a long running process from consuming cpu time during knit'ing, I suggest you consider using the knitr caching facilities to cache long running chunks and forget about :eval never-export.

In my own workflow, I routinely start the day by knit'ing a document to populate a fresh R session with objects that were cached and load libraries that are used. Then I can interactively try out modifications, export a new *.Rnw (or whatever) and knit again.

If this doesn't appeal to you then read on...

The problem is that ox-ravel replaces any #+RESULT: with the src block rendered as a chunk.
It does this by using babel to evaluate the src block using a babel language called ravel out of view of the user. So :eval never-export will break this.

In your example, without :eval never-export the :1 will be overwritten.

The only way to prevent this from happening it to hide the #+RESULT: line in some way before babel runs. One way to do this is to use something like

#+BEGIN_SRC emacs-lisp
  (defun hide-results (bk)
    (while (search-forward "#+RESULTS"  nil t)
      (replace-match "# RESULTS" nil t)))
#+END_SRC

in org-export-before-processing-hook. This will change the line to a comment in the copy buffer, but leave the original unchanged. Be warned that this will break things downstream if you ever use the #+RESULTS as input to a src block that is eval'ed during the export process.

As I mentioned, :eval never-export will prevent babel from rendering that src block as a chunk. So you need to change that. If :eval yes doesn't work for you, you will need a function to sort matters out. Something like :eval (never-plain-export) where never-plain-export is an elisp function like

#+BEGIN_SRC emacs-lisp
  (defun never-plain-export ()
    (if (memq org-export-current-backend '(html latex))
      "no"  "yes"))
#+END_SRC

that returns a string that allows export for ravel backends and interactively, but not for latex, etc.

tagteam commented 7 years ago

Well, in addition to a very intuitive cache system (results are visuable in the file) my main motivation for :eval never-export is to simplify debugging. This may break reproducibility but here is a quote from the org mailing list (Ista Zahn):

Unless you've restored sanity by setting org-export-babel-evaluate to nil. Personally I think this is not a good default. Source block evaluation and export are distinct actions, and I don't see why they should be linked by default.

Anyway, my intention with ox-ravel is to export only code to Rmd (my students will produce the results interactively in R-studio) so for this application it would actually not be a problem but wanted that #+RESULTS are ignored ...

But a SRC block with parameters :export code :eval never (or :eval "no" or :eval no) does not show in the Rmd export. I can see the problems that you describe, but would it be possible to have a user-option which allows what I want (R-SRC blocks are not evaluated but still exported to Rmarkdown chunks) at the cost of #+RESULTS being ignored and maybe some other problems?

chasberry commented 7 years ago

Well if this is all you need:

R-SRC blocks are not evaluated but still exported to Rmarkdown chunks

delete all of your :eval never-export directives from R src blocks. Put this line in your org file and C-c C-c it.

#+property: header-args:R :eval (never-plain-export)

Add any other backends you need to prevent evaluation under to the list '(html latex) in the defun for never-plain-export. If you want to export under plain latex, etc., and have the existing #+RESULTS show up in the export, change the :exports code directives to :exports both. Put the defun for never-plain-export in your init file or be sure to eval it before exporting.

Then you can have #+RESULTS: blocks in your .org, they will export if you ever want that under latex or html or whatever else you specify without re-eval-ling the R code, and ravel will render your src blocks to chunks in an `.Rmd` file but clean out the #+RESULTS blocks.

tagteam commented 7 years ago

yes, setting :exports both does it. thanks a lot!