cli icon indicating copy to clipboard operation
cli copied to clipboard

cl_dl output is missing if string contains `#` or `'`

Open fmichonneau opened this issue 2 years ago • 12 comments

library(cli)

cli_dl(
  c(
    "test_1" = "all good",
    "test_2" = "not #good"
  )
)
#> test_1: all good
#> test_2:

Created on 2021-11-02 by the reprex package (v2.0.1)

fmichonneau avatar Nov 02 '21 21:11 fmichonneau

it looks like ' and " are also causing some trouble:

cli::cli_dl(c("test_3" = "no' good either"))
#> test_3:
cli::cli_dl(c("test_4" = "no\" good also"))
#> test_4:

fmichonneau avatar Nov 03 '21 00:11 fmichonneau

This was an issue with {glue}: https://github.com/tidyverse/glue/issues/193 and was fixed in the latest release, but now brings up a new problem:

cli::cli_text("{.url https://example.com/#section}")
#> Error in glue_data(.x = NULL, ..., .sep = .sep, .envir = .envir, .open = .open, : Unterminated comment

Created on 2021-11-10 by the reprex package (v2.0.1)

zkamvar avatar Nov 10 '21 15:11 zkamvar

This behavior is fixed if you put the strings as variables, however:

url <- "https://example.com/#section"
cli::cli_text("{.url {url}}")
#> <https://example.com/#section>
msg <- "no' good either"
cli::cli_dl(c("test_3" = "{msg}"))  
#> test_3: no' good either

Created on 2021-11-10 by the reprex package (v2.0.1)

This is explicitly tested in https://github.com/r-lib/cli/blob/1af3d91f64fff903685c58e94933210968f72570/tests/testthat/test-inline.R#L50-L56

zkamvar avatar Nov 10 '21 16:11 zkamvar

I think probably cli should set comment = character() when calling glue to work around the # issue. For the unpaired quote issues I guess we would need to add an option to disable tracking of quotes when parsing.

jimhester avatar Nov 10 '21 17:11 jimhester

It would certainly help when providing a Klingon translation to messages (in a romanized script):

cli::cli_alert_success("Qapla'")

zkamvar avatar Nov 12 '21 00:11 zkamvar

This was fixed by 64a389ecbeff1fd31443f9b34553d697cfef97c0, but I messed up the issue number reference....

gaborcsardi avatar Feb 09 '22 13:02 gaborcsardi

Unfortunately I'll have to re-open this temporarily because it breaks some revdeps, and there is no way to escape braces with .literal, it seems. So until we change that or come up with another solution, the quotes will not work, and you'll need to substitute them in. The comments will be fine, because glue has a separate argument for ignoring them.

gaborcsardi avatar Feb 10 '22 12:02 gaborcsardi

Opened in 5ee4974370867c8e37933c2d479b70de39c3ce80

gaborcsardi avatar Feb 10 '22 12:02 gaborcsardi

For the record, AFAICT the problematic cli functions are cli_dl(), cli_process_start() and co. (deprecated) and cli_progress_step(), because they stitch on classes to the user input. This is definitely an anti-pattern, and I'll try to avoid it. That improves the situation because people only need to worry about quotes if they use them within braces.

❯ cli_dl(c(x = "foobar'"))
Error in glue_data(.x = NULL, ..., .sep = .sep, .envir = .envir, .open = .open,  :
  Unterminated quote (')

❯ cli_process_start("foobar'")
Error in glue_data(.x = NULL, ..., .sep = .sep, .envir = .envir, .open = .open,  :
  Unterminated quote (')

❯ cli_progress_step("foobar'")
Error in glue_data(.x = NULL, ..., .sep = .sep, .envir = .envir, .open = .open,  :
  Unterminated quote (')

gaborcsardi avatar Apr 28 '22 11:04 gaborcsardi

I have just been re-reminded of this issue.

Currently googledrive's basic messaging about files won't work if the name contains, e.g., a single quote. Which is a fairly common phenomenon.

The way I call cli::cli_bullets() is a bit more complicated than this, but boils down to this:

x <- c(
  "Drive file:",
  "*" = "{.file boring_file_name} {cli::col_grey('<id: 1_CqHhC>')}"
)
cli::cli_bullets(x)
#> Drive file:
#> • 'boring_file_name' <id: 1_CqHhC>

x <- c(
  "Drive file:",
  "*" = "{.file I'm a challenging file name} {cli::col_grey('<id: 1_CqHhC>')}"
)
cli::cli_bullets(x)
#> Error in glue_data(.x = NULL, ..., .sep = .sep, .envir = .envir, .open = .open, : Unterminated quote (')

(In real life, I have written a custom inline style for Google Drive file names, instead of .file, but we can see the problem with .file.)

I'm not even quite sure where I could insert .literal = TRUE (in the glue sense) into my cli workflows / calls to fix this situation.

jennybc avatar May 20 '22 16:05 jennybc

The pattern that works is

fn <- "I'm a challenging file name"
x <- c(
  "Drive file:",
  "*" = "{.file {fn}} {cli::col_grey('<id: 1_CqHhC>')}"
)
cli::cli_bullets(x)

gaborcsardi avatar May 27 '22 16:05 gaborcsardi

In general, to fix this cli needs its own parser, because the current cli extensions cannot be parsed properly with multiple rounds of glue with some combination of .literal = TRUE and .literal = FALSE.

gaborcsardi avatar May 27 '22 16:05 gaborcsardi