To give some context, I'm wrapping up a tiny package that references and cites R packages on the fly in Quarto/R Markdown. The package contains a single function that is intended to be used in a rendering context only (it's technically possible to run the function in a different context but the output would be quite useless).
The helpers set up temporary files/directory and render R Markdown documents locally, which is also what I need to do to make the examples.
This is a draft but here're the helpers:
template <- "
---
title: test
bibliography: %s
---
```{r include = FALSE}
library(foo)
```
%s
## References
"
dedent <- function(x) {
indentation <- sub("(?s)\\S*\n(\\s*).+", "\\1", x, perl = TRUE)
x <- gsub(paste0("(?m)^", indentation), "", x, perl = TRUE)
trimws(x)
}
render <- function(...) {
rmarkdown::render(..., output_format = "md_document", quiet = TRUE)
}
local_rmd <- function(lines, ...) {
withr::local_tempfile(lines = lines, fileext = ".Rmd", ...)
}
local_bib <- function(lines, ...) {
withr::local_tempfile(
lines = if (missing(lines)) "" else lines,
fileext = ".bib",
...
)
}
get_template <- function(bib, lines) {
sprintf(dedent(template), bib, lines)
}
local_files <- function(rmd_lines, bib_lines, env = parent.frame()) {
dir <- withr::local_tempdir(.local_envir = env)
bib <- local_bib(bib_lines, tmpdir = dir, .local_envir = env)
template <- get_template(bib, rmd_lines)
rmd <- local_rmd(template, tmpdir = dir, .local_envir = env)
list(dir = dir, rmd = rmd)
}
read_local_file <- function(dir, ext = "md") {
file <- list.files(dir, pattern = sprintf("\\.%s$", ext), full.names = TRUE)
readr::read_file(file)
}
as_inline_chunk <- function(...) {
paste(sprintf("`r %s`", c(...)), collapse = "\n\n")
}
local_output <- function(..., bib_lines, ext = "md") {
items <- local_files(as_inline_chunk(...), bib_lines)
callr::r(render, list(input = items$rmd))
read_local_file(items$dir, ext = ext)
}
As you can see, this isn't very portableā¦ and I'm not too keen on exporting local_output()
(the function that would generate the examples).