#' regexplain_addin #' #' @keywords internal regexplain_addin <- function() { # Get the document context. context <- rstudioapi::getActiveDocumentContext() # Get context text ctx_text <- context$selection[[1]]$text # If it is one line and evaluates to something, use that # Otherwise treat as text obj <- tryCatch({ if (grepl("\n", ctx_text)) { ctx_text } else { x <- eval(parse(text = ctx_text)) x <- as.character(x) if (length(x) == 1 && grepl("\n", x)) x <- strsplit(x, "\n")[[1]] if (length(x) > 10) { message(ctx_text, " gave ", length(x), " lines, limiting to first 10 unique lines.") x <- unique(x) x[1:min(length(x), 10)] } else x } }, error = function(e) {as.character(ctx_text)}) regex_gadget(obj) } #' regexplain gadget #' #' @import miniUI #' @import shiny #' @export regex_gadget <- function(text = NULL) { stopifnot(requireNamespace("miniUI"), requireNamespace("shiny")) ui <- miniPage( shiny::includeCSS(system.file("style.css", package = "regexplain")), gadgetTitleBar( "regexplain", right = miniTitleBarButton("done", "To Console", TRUE) ), miniTabstripPanel( selected = if (is.null(text)) "Text" else "Regex", miniTabPanel( "Text", icon = icon('file-text-o'), miniContentPanel( fillCol( textAreaInputAlt('text', label = "Text", value = paste(text, collapse = "\n"), resize = "both", width = "100%", height="90%") ) ) ), miniTabPanel( "Regex", icon = icon('terminal'), miniContentPanel( fillCol( flex = c(1, 3), fillRow( flex = c(2, 1), textInputCode('pattern', 'Regex', width = "90%", placeholder = "Enter regex, single \\ okay"), checkboxGroupInput( 'regex_options', label = "", inline = TRUE, width = "90%", choices = c("Break Lines" = "text_break_lines", "Ignore Case" = "ignore.case", "Perl Style" = "perl", "Fixed" = "fixed", "Use Bytes" = "useBytes" # , "Invert" = "invert" ), selected = c('text_break_lines') ) ), htmlOutput('result') ) ) ), miniTabPanel( "Output", icon = icon("table"), miniContentPanel( tags$p("Test output of regex on text here.") ) ), miniTabPanel( "Help", icon = icon("support"), miniContentPanel( tags$p("Help will go here.") ) ) ) ) server <- function(input, output, session) { rtext <- reactive({ x <- if ('text_break_lines' %in% input$regex_options) { strsplit(input$text, "\n")[[1]] } else input$text x }) output$result <- renderUI({ if (is.null(rtext())) return(NULL) if (input$pattern == "") { return(toHTML(paste('

', escape_html(rtext()), "

", collapse = ""))) } tryCatch({ toHTML( paste( view_regex( rtext(), sanitize_text_input(input$pattern), ignore.case = 'ignore.case' %in% input$regex_options, perl = 'perl' %in% input$regex_options, fixed = 'fixed' %in% input$regex_options, useBytes = 'useBytes' %in% input$regex_options, # invert = 'invert' %in% input$regex_options, render = FALSE, escape = TRUE), collapse = "" ) ) }, error = function(e) { toHTML(paste0("
", paste(e$message, collapse = "
"), "
"), paste('

', escape_html(rtext()), "

", collapse = "")) }) }) observeEvent(input$done, { # browser() if (input$pattern != "") { pattern <- paste0('regex <- "', escape_backslash(sanitize_text_input(input$pattern)), '"') rstudioapi::sendToConsole(pattern, FALSE) } stopApp() }) observeEvent(input$cancel, { stopApp() }) } viewer <- shiny::paneViewer(700) runGadget(ui, server, viewer = viewer) } sanitize_text_input <- function(x) { x <- gsub("(“|”)", '"', x) x <- gsub("‘|’", "'", x) x } toHTML <- function(...) { x <- paste(..., collapse = "") x <- gsub("\n", "\\\\n", x) x <- gsub("\t", "\\\\t", x) x <- gsub("\r", "\\\\r", x) HTML(x) }