How can I get a printed error message in RMarkdown to collapse into a single block when the error message itself was modified to print in red?
In this example collapse = T
works as expected.
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, collapse = TRUE)
```
```{r error=T}
x <- c(1,2,3,4,5)
x * 10
X * 10
```
In this example, I modified the error message to be formatted in red (based on this answer). But then it doesn't collapse with the rest:
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, collapse = TRUE)
knitr::knit_hooks$set(error = function(x, options) {
paste0("<pre style=\"color: red;\"><code>", x, "</code></pre>")
})
```
```{r error=T}
x <- c(1,2,3,4,5)
x * 10
X * 10
```
I tried to specify collapse = T
again in the specific code chunk but this won't work either:
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, collapse = TRUE)
knitr::knit_hooks$set(error = function(x, options) {
paste0("<pre style=\"color: red;\"><code>", x, "</code></pre>")
})
```
```{r error=T, collapse = T}
x <- c(1,2,3,4,5)
x * 10
X * 10
```
With the current development version of knitr (remotes::install_github('yihui/knitr')
), you can specify the CSS class for error messages. Here is an example:
```{r setup, include=FALSE}
knitr::opts_chunk$set(collapse = TRUE)
```
```{css, echo=FALSE}
.red {
color: red;
padding-top: 0;
margin-top: -15px;
border-top-color: #f5f5f5;
}
```
```{r error=T, class.error='red'}
x <- c(1,2,3,4,5)
x * 10
X * 10
```
Output:
When knitting to HTML, the highlighting is done in the last step, when the site is generated. The collapsing of chunks is done prior to that.
What complicates this is the fact that errors are highlighted just like strings and cannot be distinguished from actual string output.
Adding classes by altering a hook (like ```{.myClass} ...source code... ```
) does not help us, since this will break the chunk collapsing mechanism and even if I fix this (can be done by simply changing the underlying regex inside the chunk hook) the class is not present anymore when the site has rendered.
So in the end I only came up with the following.
---
title: "test"
output: html_document
---
<script>
$(document).ready(function() {
window.setTimeout(function() {
$(".hljs-comment:contains('####')").css("color", "red");
var tmp = $(".hljs-comment:contains('####')").text();
$(".hljs-comment:contains('####')").text(tmp.replace("####", "##"));
}, 15);
});
</script>
# Header 1
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, collapse = T)
default_hook <- knitr::knit_hooks$get("error")
knitr::knit_hooks$set(error = function(x, options) {
x <- paste0("##", x)
default_hook(x, options)
})
```
```{r error=T}
x <- c(1,2,3,4,5)
x * 10
X * 10
```
Here we change the error hook in that sense that two additional hashes are prepended to the output. In the Javascript snippet we then look for these lines, change the font color to red and delete the hashes again. This is done with a delay of 15ms. Why? If we execute the code immediately, the elements carrying the classes generated by highligh.js are not yet present. So we have to be a little slower.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With