Patrick McCarthy
Patrick McCarthy

Reputation: 2538

Knitr and tangle code without execution

I'm trying to convert a pretty critical database interface script to R markdown for documentation purposes, with the intent of then tangling that file to produce the R code that goes into my crontab. I've found however that if I set eval=T then kniting the file runs the code (which I don't want to happen unexpectedly) and if I set eval=F then tangling the file produces all commented code.

Is there a safe way to produce a file that tangles into runnable code without running the risk of execution? I suppose I could find/replace eval=F every time but that seems inelegant.

Upvotes: 3

Views: 2859

Answers (2)

Donal O'Leary
Donal O'Leary

Reputation: 61

Revisiting this question years later, there is a much easier answer:

You can combine the code chunk arguments eval=FALSE, comment=NA to:

  1. Avoid running the code chunk when running knit(), and
  2. Print code without comments when running purl()

This argument is described on the page: https://yihui.org/knitr/options/ in a section called "Code Decoration".

Perhaps this is already described in another post somewhere, but I just spent hours trying to figure out how to do this with "hooks" and knitr source code before finding the answer that I knew must be out there. Hope this makes it easier for the next person!

Upvotes: 5

Yihui Xie
Yihui Xie

Reputation: 30174

I think you can achieve this by writing a chunk hook function. See the source code of knitr::hook_purl for an example. Here is a quick and dirty solution:

library(knitr)
knit_hooks$set(purl = function(before, options) {
  if (before) return()
  input  = current_input()  # filename of input document
  output = paste(tools::file_path_sans_ext(input), 'R', sep = '.')
  if (knitr:::isFALSE(knitr:::.knitEnv$tangle.start)) {
    assign('tangle.start', TRUE, knitr:::.knitEnv)
    unlink(output)
  }
  cat(options$code, file = output, sep = '\n', append = TRUE)
})

If you set up this chunk hook in your document, all code chunks will be written out, regardless of the chunk option eval = TRUE or FALSE. Note you have to put this in the first code chunk in your document.

If your input document has a simple structure (e.g. no cross-chunk references), there is an even easier approach: you can obtain all code chunks via knitr:::knit_code$get(), and all you need to do is to write all of them to an R script.

Upvotes: 4

Related Questions