VerbalExpressions / RVerbalExpressions

:speech_balloon: Create regular expressions easily
https://rverbalexpressions.netlify.com/
Other
280 stars 12 forks source link

Consider crayon dependency for fancy output #6

Closed tylerlittlefield closed 5 years ago

tylerlittlefield commented 5 years ago

When expressions get large, it might be nice to visualize it in a way that makes it more clear. With crayon we could add a function rx_pretty() that would adjust the text style, text color, and background color of either the match characters (default) or special characters.

# highlights match or special characters
rx_pretty <- function(.data, txt_style = "bold", txt_col = "black", 
                      bg_col = "white", inverse = FALSE) {
  esc <- c(".", "|", "*", "?", "+", "(", ")", "{", "}", "^", "$", "\\", ":", "=", "[", "]")
  values <- strsplit(.data, "")[[1]]

  if(inverse) {
    esc_idx <- which(values %in% esc)
  } else {
    esc_idx <- which(!values %in% esc)
  }

  txt <- crayon::make_style(txt_col)
  bg <- crayon::make_style(bg_col, bg = TRUE)
  fancy <- crayon::combine_styles(txt, bg)

  cat(replace(values, esc_idx, crayon::style(fancy(values[esc_idx]), as = txt_style)), sep = "")
}

f <- rx() %>% 
  rx_start_of_line() %>% 
  rx_find('http') %>% 
  rx_maybe('s') %>% 
  rx_find('://') %>% 
  rx_maybe('www.') %>% 
  rx_anything_but(' ') %>% 
  rx_end_of_line()

Default behavior:

f %>% 
  rx_pretty()
Screen Shot 2019-03-08 at 1 30 16 PM

Inverse behavior:

f %>% 
  rx_pretty(inverse = TRUE)
Screen Shot 2019-03-08 at 1 31 27 PM

Custom behavior:

f %>% 
  rx_pretty(
    txt_style = "italic", 
    txt_col = "white", 
    bg_col = "blue"
    )
Screen Shot 2019-03-08 at 1 32 24 PM
tylerlittlefield commented 5 years ago

The above rx_pretty() (or maybe rx_highlight()) would need to be tweaked slightly to highlight situations where special characters should actually be considered matched. In other words, if I want to find ^, it needs to highlight. Since sanitize() adds a backslash to each special character that the user wants to match, we can find those backslash and highlight the character 1 position ahead:

# highlights match or escape characters
rx_pretty <- function(.data, txt_style = "bold", txt_col = "black", 
                      bg_col = "white", inverse = FALSE) {
  esc <- c(".", "|", "*", "?", "+", "(", ")", "{", "}", "^", "$", "\\", ":", "=", "[", "]")
  values <- strsplit(.data, "")[[1]]
  back_slashes <- lapply(strsplit(.data, ''), function(x) which(x == '\\'))

  if(inverse) {
    esc_idx <- c(which(values %in% esc), back_slashes[[1]] + 1)
  } else {
    esc_idx <- c(which(!values %in% esc), back_slashes[[1]] + 1)
  }

  txt <- crayon::make_style(txt_col)
  bg <- crayon::make_style(bg_col, bg = TRUE)
  fancy <- crayon::combine_styles(txt, bg)

  cat(replace(values, esc_idx, crayon::style(fancy(values[esc_idx]), as = txt_style)), sep = "")
}
Screen Shot 2019-03-08 at 6 31 04 PM

Note how this version correctly highlights the : in :// and . in www.

dmi3kno commented 5 years ago

This might have educational value, but I am not sure it justifies added dependency. The whole point of the package is for user to "not see" the resulting pattern and just pass it to matching function and experience, what Miles McBain calls "magic moment".

i am concerned that users will pass "prettied" regex into parsing engine (knowingly or not).

tylerlittlefield commented 5 years ago

Agreed, closing.