4

I have produced a dynamic document using knitr. The document makes extensive use of the package's knit_expand() function for templates. This is illustrated by the MWE (based on Yihui Xie's own example for the function).

  • Main document knit-expand-MWE.Rnw

    \documentclass{article}
    
    \title{How to extract code when using\\
    knit\_expand() for templates?}%
    \author{Knitr User}
    
    \begin{document}
    
    \maketitle
    \tableofcontents
    
    \newpage
    \section{Write one row of data}
    
    Only the first two sections are evaluated.
    
    <<run-all, include=FALSE>>=
    library(knitr)
    src = NULL
    for (i in 1:3) src = c(src, knit_expand('template.Rnw'))
    @
    
    \Sexpr{paste(knit(text = src), collapse = '\n')}
    
    \end{document}
    
  • Template template.Rnw called by main document

    \subsection{Now i is {{i}}}
    
    This chunk is {{if (i > 2) 'not '}}evaluated.
    <<row-{{i}}, eval={{i <= 2}}>>=
    # row number {{i}}
    iris[{{i}}, ]
    @
    

I now need to extract the corresponding R code. Running purl("knit-expand-MWE.Rnw") outputs knit-expand-MWE.R, which includes the code in the chunk with a reference to the template:

## ----run-all, include=FALSE----------------------------------------------
library(knitr)
src = NULL
for (i in 1:3) src = c(src, knit_expand('template.Rnw'))

What I would like instead is the corresponding "expanded" code (for the benefit of colleagues who do not use knitr), for example:

## ----row-1, eval=TRUE----------------------------------------------
## row number 1
iris[1, ]

## ----row-2, eval=TRUE----------------------------------------------
## row number 2
iris[2, ]

## ----row-3, eval=FALSE----------------------------------------------
## row number 3
iris[3, ]

How can I achieve this?

1 Answers1

2

You can run purl() on src, e. g.

purl(text = src, output = 'knit-expand.R')
Yihui Xie
  • 28,913
  • 23
  • 193
  • 419
  • In the MWE, putting that line of code at the bottom of the `run-all` chunk does the trick. But if the chunk is instead in a child document called by the main document, then the compilation chokes with this error: `## Error in parse block(g[-1], g[1], params.src): duplicate label ’row-1’`. Is there a way around this? – Laura Fortunato Aug 24 '17 at 20:55
  • 1
    I'm not quite sure if the error makes sense in this case, but you can suppress it by setting `options(knitr.duplicate.label = 'allow')`. – Yihui Xie Aug 25 '17 at 04:00
  • I **believe** the issue is that both `knit_child()` and `purl()` effectively call `knit()` on `src`, which leads to the duplicate labels (there are no duplicate labels otherwise). So the option you suggest above resolves the issue. Thanks Yihui! – Laura Fortunato Aug 28 '17 at 17:58
  • You are right that `purl()` essentially calls `knit()`, which caused the issue of duplicated labels. – Yihui Xie Aug 28 '17 at 19:27