r-lib / ansistrings

Manipulation of ANSI colored strings
Other
9 stars 5 forks source link

Escape 39 not processed? #20

Open lionel- opened 6 years ago

lionel- commented 6 years ago

The quosure deparser always adds "default foreground" escape codes when printing a quosure from the global environment. This is for ease of implementation because the deparser is called recursively in case of nested quosures. It appears ansistrings does not process this escape:

str <- rlang:::quo_deparse(quo(foo))
str
#> [1] "\033[39m^foo\033[39m"

html <- ansistrings::ansi_to_html(str, FALSE)
unclass(html)
#> [1] "\033[39m^foo\033[39m"

Surprisingly it works correctly if other escapes are in the string. Here I unquote a local quosure to introduce a nested colour in the string:

str2 <- rlang:::quo_deparse(quo(foo(!!local(quo(bar)))))
str2
#> [1] "\033[39m^foo(\033[34m^bar\033[39m)\033[39m"

html2 <- ansistrings::ansi_to_html(str2, FALSE)
unclass(html2)
#> [1] "^foo(<span style=\"color:#3465a4\">^bar</span>)"
gaborcsardi commented 6 years ago

ansistrings currently only handled well-formed sequences, e.g. the ones generated by crayon.

lionel- commented 6 years ago

I cannot use crayon, do you see what's wrong in the sequence?

gaborcsardi commented 6 years ago

there is nothing wrong with it, just ansistrings/crayon do not use it. If it is widely implemented, then they should.

gaborcsardi commented 6 years ago

So, 39 is the closing "tag" in crayon, essentially. I am not sure how we could use it as an opening tag.

lionel- commented 6 years ago

From what I read for instance here 39 is supposed to refer to the default colour, not the last one used (which is what using it as closing tag does I presume).

gaborcsardi commented 6 years ago

ANSI colors do not have opening and closing tags, they just change the state. So crayon commands emulate the tags, because they are much easier to work with, they compose. E.g.:

cat(crayon::red(paste("pre", crayon::green("in"), "post")))

Without this, coloring the output would be nightmare. This is basically the single cool feature of crayon.

It would be nice to have a "default color" tag (and another one for the bg), but I am not sure if it is possible to implement that.

All this said, ansistrings should support arbitrary (even invalid) sequences.

lionel- commented 6 years ago

oh no worries, I'm adding escape codes "manually". I agree that crayon should be about balanced tags.

brodieG commented 6 years ago

FWIW, I'm pretty close to finishing fansi which should support this and unbalanced tags.

gaborcsardi commented 6 years ago

The problem with the manual tags is that they might not compose. E.g. if I want to include your output in a paragraph, that has a certain color (e.g. because it is in the report of a testthat test failure, so it is red), then your escape code just makes this hard.

Maybe there is a way to have a nice "default color" tag that crayon can work with. (You can still add it manually, it does not matter how it is added.) Right now, using 39 as both the start and end tag confuses crayon.

gaborcsardi commented 6 years ago

Btw. AFAIR @brodieG looked into this a bit, i.e. having a "default style" tag, and it was a bit cumbersome.

brodieG commented 6 years ago

Yeah, this is what I had looked at.