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.
CodePudding user response:
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 checkexpects 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,
roxygen2seems to do some preprocessing, since the above generates the following\examples{}block:\examples{ \if{html}{\out{<div >}}\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\donttestmacros. They are handled exceptionally byR CMD check, but not by theknitrvignette 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 = FALSEseems OK, but then the first line isn't evaluated.) Hence, even if@includeRmdcould 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.
