yihui / knitr

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

`attr.output` has no effect #2256

Closed mcanouil closed 1 year ago

mcanouil commented 1 year ago

attr.output has no effect either in Quarto or rmarkdown.

Using the following code chunk/cell:

---
title: "Demo"
output:
  html_document:
    keep_md: true
---

```{r}
#| error: true
#| warning: true
#| message: true
#| attr.output: "style='color: blue;'"
#| attr.error: "style='color: yellow;'"
#| attr.warning: "style='color: orange;'"
#| attr.message: "style='color: green;'"
#| results: asis
cat("something")
stop("something")
warning("something")
message("something")

Using `rmarkdown`, it produces the below markdown file which already has no attributes for output while for error/warning/message the attribute is there.

````md
---
title: "Demo"
output:
  html_document:
    keep_md: true
---

```r
cat("something")

something

stop("something")
## Error in eval(expr, envir, enclos): something
warning("something")
## Warning: something
message("something")
## something

Same pattern is observed via Quarto (https://github.com/quarto-dev/quarto-cli/issues/5456)
![image](https://user-images.githubusercontent.com/8896044/236916303-5016cd2f-0091-4da1-af4c-2deec45f1217.png)

---

knitr: 1.42
R: 4.3.0
OS: MacOS

```txt
R version 4.3.0 (2023-04-21)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.3.1

Locale: en_US.UTF-8 / en_US.UTF-8 / en_US.UTF-8 / C / en_US.UTF-8 / en_US.UTF-8

time zone: Europe/Paris
tzcode source: internal

Package version:
  evaluate_0.20   graphics_4.3.0  grDevices_4.3.0 highr_0.10      knitr_1.42      methods_4.3.0   stats_4.3.0     tools_4.3.0     utils_4.3.0    
  xfun_0.39       yaml_2.3.7     

By filing an issue to this repo, I promise that

I understand that my issue may be closed if I don't fulfill my promises.

cderv commented 1 year ago

This is just happening because you are using results: asis

This means no code chunk output will be created to put the attributes on. Asis output will be output asis in the resulting document.

See

---
title: "Demo"
output:
  html_document:
    keep_md: true
---

```{r}
# Set global option
knitr::opts_chunk$set(attr.output = "style='color: blue;'")
#| results: asis
cat("something")
cat("something")

![image](https://user-images.githubusercontent.com/6791940/237035387-776f8e90-1d4c-4a94-bc63-9e0139a57fe8.png)

And intermediate source code 

````markdown
---
title: "Demo"
output:
  html_document:
    keep_md: true
---

```r
# Set global option
knitr::opts_chunk$set(attr.output = "style='color: blue;'")
cat("something")

something

cat("something")
## something


There is no issue here - just an unexpected usage of `attr.output`. 

For message, error and warning, `asis` does not apply so that is why you get the correct wrapping in `.md` file with correct class. 
ateucher commented 1 year ago

That makes sense, thanks for the illustration. What about image output? Is it always treated as 'asis'?

---
title: "Demo"
output:
  html_document:
    keep_md: true
---

```{r}
# Set global option
knitr::opts_chunk$set(attr.output = "style='border: 5px solid blue;'")
plot(hp ~ cyl, data = mtcars)
cat("something")

![image](https://github.com/yihui/knitr/assets/2816635/2cef9c4d-2d29-4640-87f5-565c6f1926b9)

and intermediate markdown:

````markdown
---
title: "Demo"
output:
  html_document:
    keep_md: true
---

```r
# Set global option
knitr::opts_chunk$set(attr.output = "style='border: 5px solid blue;'")
plot(hp ~ cyl, data = mtcars)

cat("something")
## something
mcanouil commented 1 year ago

Thanks for the detailed explanation. I see that the behaviour is "driven" by the use of fenced code blocks.

What if results: asis + attr.output: "style='color blue;', instead of using fenced code blocks which is not possible for results: asis fenced divs were used?

The following

---
title: "Demo"
output:
  html_document:
    keep_md: true
---

```{r}
#| attr.output: 'style="color: blue;"'
#| results: asis
cat("something")

would then produce the below markdown code which should work properly in Pandoc:

````md
---
title: "Demo"
output:
  html_document:
    keep_md: true
---

```r
cat("something")

:::{style="color: blue;"} something :::


And if nothing is given to `attr.output`

````md
---
title: "Demo"
output:
  html_document:
    keep_md: true
---

```r
cat("something")

something

cderv commented 1 year ago

Putting back what I said on slack

we could indeed to that but it is not obvious to me it should behave this way. results = 'asis' means to consider the code output as content to not process specifically and output results asis. If one needs fenced divs to set classes or attributes, then the code content should generate itself this fenced div and not knitr. It behave like this for raw block, I should behave the same for fenced div IMO. We could add a helper though to make that easier like for raw block e.g knitr::fenced_divs()

I think if there is a strong use case, it would be good to consider, but for now it is easy enough to add a hook if a user needs to automate that, or add the ::: as part of the cat()-ed output.

To note that usually when using results: 'asis', you don't echo source code and this can be written

::: {style="color: blue;"}
```{r}
#| echo: false
#| results: asis
cat("something")

:::



But maybe I am missing the use case that requires that. 

Also Quarto and R markdown differs on how they handle this so could be something to do / improve in Quarto as it adds already some divs around code and output chunk.
mcanouil commented 1 year ago

On second thought, maybe there is something that could be done in Quarto. Currently, you can use classes to add classes to the cell container, maybe there should be an attributes which would be more general as for class.* and attr.* in knitr. This would allow a whole new customisation set on cell container.

cderv commented 1 year ago

Yes in Quarto you have different tooling, and it aims to be language agnostic (if done on knitr, only for R). Quarto wraps in divs at several layers - quite complex already though, with some challenge to move attributes / classes to the right place.

But again, what is the use case ? Why is this needed ? I think such new addition should be driven by a usage, and not just the question that it could be done. Just personal thoughts.

Happy to add such support in knitr if there is a clear use case we could check and think this through.

mcanouil commented 1 year ago

In Quarto, being able to add attributes other than class allows to use many things, such as tooltip, hover effect, aria-, etc. to a code cell. I am not sure it would be really complex to add such things, unless you want to notify the user he/she is doing nonsense html thing, and even if that's the case Pandoc will basically prepend data- to the whole value of attributes which in the end should be harmless.

Regarding knitr, it makes sense to keep the behaviour as is for results: asis and play around Quarto for both Jupyter and knitr engines.

cderv commented 1 year ago

I'll close this here, and we can keep discussion in Quarto to see what should be added, where and why !

Thank @mcanouil for the ideas and suggestions !

github-actions[bot] commented 11 months ago

This old thread has been automatically locked. If you think you have found something related to this, please open a new issue by following the issue guide (https://yihui.org/issue/), and link to this old issue if necessary.