yihui / knitr

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

output hooks and current chunk options #2333

Open cderv opened 3 months ago

cderv commented 3 months ago

I don't know if this is expected behavior, or an issue to fix, but this would be some improvement.

It seems output hook is using options sets by engine or function in the chunk (like options$results = 'asis'), but others like chunk hook will only use the current chunk option as the one set in the source code

Example

```{r, echo=FALSE}
knitr::knit_engines$set(demo = function(options) {

    options[["results"]] <- "asis"

    knitr::engine_output(
      options,
      options$code,
      out = "Should be `asis` content."
    )
  })

local({
  ohook <- knitr::knit_hooks$get("chunk")
  knitr::knit_hooks$set(chunk = function(x, options) {
    if (options$results != "asis" && nzchar(x)) {
      x <- paste(c("::: {.wrapped}", x, ":::"), collapse = "\n")
    }
    ohook(x, options)
  })
  ohook2 <- knitr::knit_hooks$get("output")
  knitr::knit_hooks$set(output = function(x, options) {
    x <- ohook2(x, options)
    if (options$results != "asis" && nzchar(x)) {
      x <- paste(c("::: {.internal}", x, ":::"), collapse = "\n")
    }
    x
  })
})
1 + 1
Do no matter

````r
> knitr::knit("test.Rmd"); xfun::file_string("test.md")

processing file: test.Rmd

output file: test.md

[1] "test.md"

::: {.wrapped}

```r
1 + 1

::: {.internal}

## [1] 2

::: :::

::: {.wrapped}

Do no matter

Should be asis content.

:::



The `.wrapped` div is never removed, while the `.internal` div is removed if the `results == "asis"` as set by the engine in this example. 

This is related to 
* https://github.com/quarto-dev/quarto-cli/issues/9184

Currently in Quarto only setting `output: asis` explicitly on the cell will allow to remove the external wrapping of output. 

Quarto redifines the chunk hook for this wrapping and checks the `options$results`

I wonder if there should be a mechanism for **knitr** hooks to consider the options as redefined possibly by the cell behavior and not just the explicit definition on cell options.