Collapse error message into a single block when the error message is modified to print in red

喜夏-厌秋 提交于 2021-01-02 06:17:33

问题


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
```   

回答1:


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.




回答2:


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:



来源:https://stackoverflow.com/questions/54976794/collapse-error-message-into-a-single-block-when-the-error-message-is-modified-to

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!