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

Add option to customize last separator when auto-collapsing character vectors #639

Closed
Teebusch opened this issue Oct 19, 2023 · 4 comments
Closed

Comments

@Teebusch
Copy link

Teebusch commented Oct 19, 2023

cli_text() and pluralize() auto-collapse character vectors, but there is no option to configure the final separator "and":

pkgs <- c("pkg1", "pkg2", "pkg3")
cli_text("Will remove the {.pkg {pkgs}} package{?s}.")
#> Will remove the pkg1, pkg2, and pkg3 packages.

This is hardcoded as last in cli:::inline_collapse():

function (x, style = list()) 
{
  sep <- style[["vec-sep"]] %||% style[["vec_sep"]] %||% ", "
  if (length(x) >= 3) {
    last <- style[["vec-last"]] %||% style[["vec_last"]] %||% 
      ", and "
  }
  else {
    last <- style[["vec-sep2"]] %||% style[["vec_sep2"]] %||% 
      style[["vec-last"]] %||% style[["vec_last"]] %||% 
      " and "
  }
  trunc <- style[["vec-trunc"]] %||% style[["vec_trunc"]] %||% 
    20L
  col_style <- style[["vec-trunc-style"]] %||% "both-ends"
  ansi_collapse(x, sep = sep, last = last, trunc = trunc, 
    style = col_style)
}

It would be useful to expose a last argument to the user so they can override it with a language-specific separator or just a regular ','.

A usable workaround is to collapse the character vector outside of the function, e.g. with glue::collapse(), which does have a last argument.

@gaborcsardi
Copy link
Member

There are several ways to do this, here are two:

❯ cli_text("foo {.or {letters[1:5]}} bar")
foo a, b, c, d, or e bar
v <- cli_vec(letters[1:5], style = list("vec-last" =  ", or "))
❯ cli_text("foo {v} bar")
foo a, b, c, d, or e bar

@Teebusch
Copy link
Author

Teebusch commented Oct 19, 2023

Awesome! Thanks for the quick response! It might be worth adding to the relevant documentation article
https://cli.r-lib.org/articles/pluralization.html#use-the-length-of-character-vectors

Also worth mentioning that the first solution you suggest only is a solution if you want to replace "and" with "or"

cli::cli_text("foo {.or {letters[1:5]}} bar")
cli::cli_text("foo {.und {letters[1:5]}} bar") # won't work

And the second solution means you won't have the convenience of the automatic character vector collapsing.

@gaborcsardi
Copy link
Member

Also worth mentioning that the first solution you suggest only is a solution if you want to replace "and" with "or"

You would need define {.und}.

And the second solution means you won't have the convenience of the automatic character vector collapsing.

I am not sure what you mean, see my second example. In general, you either need to define your own class with a theme, or add the style to the vector that you want to collapse.

@Teebusch
Copy link
Author

Teebusch commented Aug 21, 2024

I ran into this issue again today and it took me a while to remember how to define a custom {.und} inline markup again.
For future me and anyone else who might need it -- Here are two ways to do it:

x <- c("a", "b", "c")
text <- "{.und {x}}"
my_theme <- list(span.und = list("vec-sep2" = " und ", "vec-last" = ", und "))

# -- option 1: modify theme temporarily for a single div

cli::cli_div(theme = my_theme)
cli::cli_text(text)
cli::cli_end()

# > a, b, und c

# -- option 2:modify theme more permanently via user theme

options("cli.user_theme" = my_theme)
cli::cli_text(text)

# > a, b, und c

Relevant sources

https://cli.r-lib.org/reference/inline-markup.html#collapsing-inline-vectors

cli/R/themes.R

Line 254 in 2ddcc1a

span.or = list("vec-sep2" = " or ", "vec-last" = ", or "),

https://cli.r-lib.org/reference/themes.html
https://cli.r-lib.org/reference/cli_div.html
https://cli.r-lib.org/reference/inline-markup.html

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

2 participants