yihui / knitr

A general-purpose tool for dynamic report generation in R
https://yihui.org/knitr/
2.36k stars 873 forks source link

customizable cache (closes #2176) #2340

Open atusy opened 2 months ago

atusy commented 2 months ago

This PR allows implementing knit_cache_hook methods which may preprocess objects (e.g., save to an external file) and define custom loaders.

I will add a NEWS item after we agree with the design.

With this PR, we can add some hooks on objects to be cached. For example, we can use writeLines to save character objects.

```{r}
library(knitr)
registerS3method(
  "knit_cache_hook",
  "character",
  function(x, nm, path) {
    # Cache x as is if it extends character class
    if (!identical(class(x), "character")) {
      return(x)
    }

    # Preprocess data (e.g., save data to an external file)
    # Create external files under the directory of `paste0(path, "__extra")`
    # if knitr should cleanup them on refreshing/cleaning cache
    d <- paste0(path, "__extra")
    dir.create(d, showWarnings = FALSE, recursive = TRUE)
    f <- file.path(d, paste0(nm, '.txt'))
    writeLines(x, f)

    # Return loader function
    # which receives ellipsis for future extentions and has knit_cache_loader class
    structure(function(...) readLines(f), class = 'knit_cache_loader')
  },
  envir = asNamespace("knitr")
)
x <- 'foo bar'
print(x)
print(x)
atusy commented 2 months ago

maybe preprocess and postprocess are not good names... :thinking:

atusy commented 2 months ago

I got to fix tests

atusy commented 2 months ago

To solve the above problems, I implemented the knit_cache_hook generic function in place of knit_cache_preprocess and knit_cache_postprocess. See updated description for the details.