rstudio / rmarkdown-cookbook

R Markdown Cookbook. A range of tips and tricks to make better use of R Markdown.
https://bookdown.org/yihui/rmarkdown-cookbook/
578 stars 224 forks source link

Use multi-line string to support multiple statements in R functions #384

Closed nanxstats closed 1 year ago

nanxstats commented 1 year ago

This PR proposes to use literal style multi-line string in YAML to support seamless formatting of R functions defined in the knit field and avoid possible confusions from indentation details.

Specifically, the current code example for customizing the knit button behavior works but does not work for any non-trivial R functions containing multiple statements. For example, let's add a print(input) call before the rmarkdown::render call. Using the current approach:

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

The function will be parsed as:

[1] "(function(input, ...) { print(input) rmarkdown::render( input, output_file = paste0( xfun::sans_ext(input), '-', Sys.Date(), '.html' ), envir = globalenv() ) })"

This does not execute:

Error: unexpected symbol in "(function(input, ...) { invisible(system(paste0('(function(input, ...) { print(input) rmarkdown::render( input, output_file = paste0( xfun::sans_ext(input), '-', Sys.Date(), '.html"
Execution halted

A workaround is adding ; after the first statement, which is non-idiomatic.

Instead, if we write

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

This will be parsed as:

[1] "(function(input, ...) {\n  print(input)\n  rmarkdown::render(\n    input,\n    output_file = paste0(\n    xfun::sans_ext(input), '-', Sys.Date(), '.html'\n  ),\n  envir = globalenv()\n  )\n})"

which can be correctly executed.

In reality, users can write the R function separately, copy and paste it here, and simply add two spaces before each line.

nanxstats commented 1 year ago

Hey @yihui, could you take a quick look at this PR when you get a chance? I think it improves one aspect of the text but not sure if there are other considerations when this was first written. Your feedback would be highly valuable. Thanks!