Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Think about how to colour html output #24

Closed
hadley opened this issue Jan 8, 2016 · 21 comments
Closed

Think about how to colour html output #24

hadley opened this issue Jan 8, 2016 · 21 comments

Comments

@hadley
Copy link
Member

hadley commented Jan 8, 2016

It would be nice if crayon also worked inside of knitr, rmarkdown, etc.

This probably requires some thinking to ensure that things are escaped correctly. (Or maybe it's the responsibility of evaluate to turn terminal escapes into the appropriate html spans)

cc @yihui

@gaborcsardi
Copy link
Member

Yeah, I thought about this, too, and will be happy to add whatever is needed.
Btw. unrelatedly, color in RStudio would be great, too. I know it is not easy....

@hadley
Copy link
Member Author

hadley commented Jan 8, 2016

Yeah, that's on the todo list

@gaborcsardi
Copy link
Member

@yihui Any idea how this could work? I guess some support is needed from pandoc as well? Does that exist?

@yihui
Copy link

yihui commented Jan 21, 2016

I don't have a clear idea about this. Maybe it is the responsibility of evaluate (around here https://github.com/hadley/evaluate/blob/master/R/watcher.r#L32) to generate HTML spans, or maybe one can use the knitr output hook (http://yihui.name/knitr/hooks/) to post-process the text output from chunks. Actually I'm not even sure if the ANSI escape codes can be preserved in the evaluate output at all (if they cannot, there is no way to move forward).

@gaborcsardi
Copy link
Member

It does not have to be ANSI, actually. crayon is adding the ANSI sequences, and it could just detect that it is inside of knitr and add whatever markup is needed instead. E.g. attach some attributes to the output.

But I think that even just passing the ANSI seqs to evaluate / knitr could work. An ANSI colored output is just a regular string, with some strange-looking markup in it, so the output hook is worth a try. I'll take a look in a sec.

@gaborcsardi
Copy link
Member

OK, I tried it. The ANSI markup goes through, so I just need an output hook that interprets it, and converts it to HTML. \o/

@gaborcsardi
Copy link
Member

So, it works very well IMO. Here is an example:
https://gist.github.com/gaborcsardi/1fafd4f6c795f00989b8#file-test-rmd

You can see the output here:
https://htmlpreview.github.io/?https://gist.githubusercontent.com/gaborcsardi/1fafd4f6c795f00989b8/raw/11f132b17ba317cd4ee2408a418c400353561a3d/test.html

What would be the best way to ship this? A function in the crayon package that sets up the knitr output hooks? Or you want to put this within knitr? Or a third package?

I think you could even turn this on by default in the default html hooks.

Unfortunately AFAIK there is no way to color a markdown document, at least not with GFM. :(

@yihui
Copy link

yihui commented Jan 22, 2016

Maybe a function in crayon like hook_output_crayon() so that users can opt-in by setting the output hook to this function? You can condition the behavior on a chunk option, say, crayon = TRUE (i.e. do gsub() only when isTRUE(options$crayon)).

@gaborcsardi
Copy link
Member

OK, I can do that. I would turn it on by default, though. I mean, once the hooks are set, it is on, and you can turn it off with a chunk option. It would be very annoying to turn it on manually all the time, and (for HTML output), it is harmless.

Btw. this approach is not very good if you have both markdown and html output, because the markdown will have the ANSI seqs, but I guess I can just add a markdown output hook to remove them.

@yihui
Copy link

yihui commented Jan 22, 2016

"Turning it on manually all the time" will be annoying if many people actually use this hook. I'm not sure this will be so popular that I need to support it "officially" (which means I'll introduce a Suggests dependency in knitr, and perhaps spend some time on maintaining this hook in the future). I like the colored terminal output, but personally I'm not very interested in colored output in HTML, so my current decision is if you want this feature, you opt in by setting the output hook.

@gaborcsardi
Copy link
Member

It will be annoying if many people actually use this hook.

Well, the last thing I want is to annoy people. :)

@wlandau-lilly
Copy link

wlandau-lilly commented Nov 20, 2017

Are there any new thoughts on this issue? I am not sure I understand why such a hook would be annoying. I would like to use it for my own reports, but I cannot view the gist. I also posted here.

@yihui
Copy link

yihui commented Nov 20, 2017

@wlandau-lilly If you are asking me, the answer is no. I'm not interested in this feature, but knitr is open --- you don't really need my specific support. You should be able to opt in by yourself.

@wlandau-lilly
Copy link

@yihui I do not care where or how it is implemented, and I agree that knitr is probably not the right place. To be honest, right now I am just looking for a temporary solution. I do not know how to create such a hook myself.

@wlandau-lilly
Copy link

wlandau-lilly commented Nov 21, 2017

I would love to have functions in crayon to convert coloring between ANSI and HTML. Then, it would be easy to write a knitr output hook, and the usefulness would extend beyond knitr.

@wlandau-lilly
Copy link

wlandau-lilly commented Nov 21, 2017

This seems to work:

---
title: "MWE"
output: html_document
---

```{r color, echo = FALSE}
options(crayon.enabled = TRUE)
knitr::knit_hooks$set(message = function(x, options){
  paste0(
    "<pre class=\"r-output\"><code>",
    ansistrings::ansi_to_html(text = x, fullpage = FALSE),
    "</code></pre>"
  )
})
message(crayon::make_style("green")("My green message."))
```

Markdown output:

---
title: "MWE"
output: html_document
---

<pre class="r-output"><code>
## <span style="color:#4e9a06">My green message.</span>
</code></pre>

I look forward to the release of ansistrings.

@cderv
Copy link

cderv commented Feb 1, 2020

While trying to understand what is going on in yihui/knitr#1805, here is an update regarding opting-in for coloured html output from crayon using fansi 📦

The hook thing described above has not been included in crayon directly, but it has been in fansi with a special set_knit_hooks function.

This is useful for preserving tidyverse coloring in output, errors and others.

To render with rmarkdown::render

---
title: "MWE"
output: html_document
---

Required setup

```{r color, echo = FALSE, results='asis'}
# crayon needs to be explicitly activated in Rmd
options(crayon.enabled = TRUE)
# Hooks needs to be set to deal with outputs
# thanks to fansi logic
old_hooks <- fansi::set_knit_hooks(knitr::knit_hooks, 
                                   which = c("output", "message", "error"))
```

Enabling coloring message using crayon in Rmd

```{r, message= TRUE}
message(crayon::make_style("green")("My green message."))
```

Keeping color in tidyverse error as rlang use color

```{r, error = TRUE}
rlang::abort(rlang:::format_error_bullets(c(x = "dplyr-like error")), .subclass = "foobar")
```

Keeping the red values in tibble output

```{r}
tibble::tibble(x = c(10, -10))
```
Will give this output

image

Hoping it will help others who want to preserve R terminal colouring.

@fmmattioni
Copy link

That is a really nice solution that @cderv provided! Thank you!

One question, though: this makes the outputs to be in separate boxes.. for example, in the last example given, I would like to have both the call tibble::tibble(x = c(10, -10)) and its output in the same box. Is this possible somehow?

@cderv
Copy link

cderv commented Feb 29, 2020

Thanks @fmmattioni !

I think this question has nothing to do with the current topic of this closed issue. Please, could you ask this question in RStudio Community ? It would be a better place to have a discussion there and I could give you an answer there. Thank you very much !

@phineas-pta
Copy link

Hello,

Does this feature work with shiny::verbatimTextOutput?

@gaborcsardi
Copy link
Member

@phineas-pta craoyn does not do anything towards this, so I am afraid you'll need to ask at fansi or shiny.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants