17.5 Customize the Knit button (*)

When you click the Knit button in RStudio, it will call the rmarkdown::render() function in a new R session and output a file of the same base name as the input file in the same directory. For example, knitting example.Rmd with the output format html_document will create an output file example.html.

There may be situations in which we want to customize how the document is rendered. For example, perhaps we would like the rendered document to contain the current date, or would like to output the compiled report into a different directory. Although we can achieve these goals by calling rmarkdown::render() (see Section 17.3) with the appropriate output_file argument, it can be inconvenient to have to rely on a custom call to rmarkdown::render() to compile your report.

It is possible to control the behavior of the Knit button by providing the knit field within the YAML frontmatter of your document. The field takes a function with the main argument input (the path to the input Rmd document) and other arguments that are currently ignored. You can either write the source code of the function directly in the knit field, or put the function elsewhere (e.g., in an R package) and call the function in the knit field. If you routinely need the custom knit function, we would recommend that you put it in a package, instead of repeating its source code in every single R Markdown document.

If you store the code directly within YAML, you must wrap the entire function in parentheses. If the source code has multiple lines, you have to indent the first line by exactly two spaces and all other lines by at least two spaces. For example, if we want the output filename to include the date on which it is rendered, we could use the following YAML code in the Rmd document header:

---
knit: |
  (function(input, ...) {
    rmarkdown::render(
      input,
      output_file = paste0(
        xfun::sans_ext(input), '-', Sys.Date(), '.html'
      ),
      envir = globalenv()
    )
  })
---

For example, if we knit example.Rmd on 2019-07-29, the output filename will be example-2019-07-29.html.

While the above approach looks simple and straightforward enough, embedding a function directly in your YAML may make it difficult for you to maintain it, unless the function is only to be used once with a single R Markdown document. In general, we would recommend using an R package to maintain such a function, e.g., you may create a function knit_with_date() in a package:

#' Custom Knit function for RStudio
#'
#' @export
knit_with_date <- function(input, ...) {
  rmarkdown::render(
    input,
    output_file = paste0(
        xfun::sans_ext(input), '-', Sys.Date(), '.'
    ),
    envir = globalenv()
  )
}

If you add the above code to a package named myPackage, you will be able to refer to your custom knit function using the following YAML setting:

---
knit: myPackage::knit_with_date
---

You may refer to the help page ?rmarkdown::render to find out more ideas on how you could customize your knit function behind the Knit button in RStudio.