R CMD check gives warning when using @includeRmd for examples using Roxygene

Solution 1:

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.