I'm writing an R package using roxygen2
for documentation. I'm using the @includeRmd
tag to reduce duplication, and this works well to generate consistent documentation across the help files, vignette, and pkgdown
website.
My only issue is that, when I use the tag to insert examples, R CMD check
gives me a nasty warning. Here is my setup:
R/adder.R
... source code for function with roxygen2
block
#' Add three numbers
#'
#' @includeRmd includes/adder_description.Rmd description
#'
#' @param x First number to add
#' @param y Second number to add
#' @param z Third number to add
#' @return The sum of the numbers
#'
#' @includeRmd includes/adder_examples.Rmd examples
#'
#' @md
#' @export
adder <- function(x, y, z) {
x+y+z
}
includes/adder_description.Rmd
... description text to be included
The `adder()` function adds three numbers.
includes/adder_examples.Rmd
... example code to be included
```{r adder_examples}
adder(3,5,6)
```
In my vignette and README
, I can insert the same description text and example code like so:
```{r child=rprojroot::find_package_root_file("includes", "adder_description.Rmd")}
```
```{r child=rprojroot::find_package_root_file("includes", "adder_examples.Rmd")}
```
All fine and dandy: the description text and example code are included consistently across the board. However, R CMD check
gives the following warning about the \examples{}
block generated by roxygen2
in man/adder.Rd
:
> checking Rd files ... WARNING
checkRd: (7) adder.Rd:23: Tag \if is invalid in a \examples block
checkRd: (7) adder.Rd:23-24: Tag \preformatted is invalid in a \examples block
checkRd: (7) adder.Rd:24: Tag \if is invalid in a \examples block
checkRd: (7) adder.Rd:24-25: Tag \preformatted is invalid in a \examples block
Looking at the .Rd
file, there certainly are some unusual tags that do not appear when I include the examples in a normal way.
My question is: Are these warnings issued because I am using the @includeRmd
tag incorrectly, or is this use case just not what the tag was intended for? It seems that the warnings would preclude submission of the package to CRAN.
Your usage of the @includeRmd
tag does not appear to be supported. You can use it to generate a Description or (sub)sections of Details, but not Examples. The documentation states:
It is currently not possible to document function arguments, return values, etc. in external Rmd documents.
That isn't too surprising, for a couple of reasons:
R CMD check
expects the \examples{}
block to contain verbatim R code, not Markdown, so injecting Markdown into the block without preprocessing is doomed to fail. Due to the chunk header and footer, the following is not valid R code:
```{r adder_examples}
adder(3, 5, 6)
```
That said, roxygen2
seems to do some preprocessing, since the above generates the following \examples{}
block:
\examples{
\if{html}{\out{<div class="sourceCode r">}}\preformatted{adder(3, 5, 6)
}\if{html}{\out{</div>}}\preformatted{## [1] 14
}
The injected text would be valid inside of \description{}
or \details{}
, but isn't valid inside of \examples{}
as it is not verbatim R code.
As exceptions to the "verbatim" rule, the \examples{}
block permits the \dontrun
, \dontshow
, and \donttest
macros. They are handled exceptionally by R CMD check
, but not by the knitr
vignette engine. You'd get a build failure if you tried to insert this chunk into a vignette:
```{r adder_examples}
adder(3, 5, 6)
\dontrun{
adder(3, 5, "6")
}
```
With chunk option eval = 1L
, the parser still throws an error. (eval = FALSE
seems OK, but then the first line isn't evaluated.) Hence, even if @includeRmd
could be used to generate a valid \examples{}
block, you wouldn't necessarily be able to share the code with a vignette.
If you really want to externalize your Examples, then you can try doing it the old-fashioned way, i.e., with a shell script and sed
, using @examples
as a marker for text insertion (some examples here). I doubt the complexity is worth it, but you can be the judge...
Update: I've just tried to hack things a bit with my own minimal package...
pkgname <- "foo"
usethis::create_package(pkgname, rstudio = FALSE, open = FALSE)
setwd(pkgname)
usethis::use_directory(file.path("inst", "examples"))
text <- "
#' @title A title
#' @description A description.
#' @param a,b Arguments.
#' @includeRmd inst/examples/add.Rmd examples
#' @export
add <- function(a, b) a + b
"
cat(text, file = file.path("R", "add.R"))
text <- "
add(1, 1)
"
cat(text, file = file.path("inst", "examples", "add.Rmd"))
roxygen2::roxygenize(".")
writeLines(readLines(file.path("man", "add.Rd")))
\examples{
add(1, 1)
}
So it seemed like deleting the chunk header and footer might allow roxygen2
to generate a sensible \examples{}
block. But I was wrong:
text <- "
add(1, 1)
add(2, 2)
"
cat(text, file = file.path("inst", "examples", "add.Rmd"))
roxygen2::roxygenize(".")
x <- readLines(file.path("man", "add.Rd"))
writeLines(tail(x, -(grep("^\\\\examples", x) - 1L)))
\examples{
add(1, 1) add(2, 2)
}
The generated text is invalid R code when the example spans two or more lines, because Markdown treats newlines like spaces.