🔍 An RStudio addin slash regex utility belt
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

171 lines
5.1KB

  1. #' @import miniUI
  2. #' @import shiny
  3. regex_gadget <- function(text = NULL) {
  4. library("shiny")
  5. library("miniUI")
  6. ui <- miniPage(
  7. shiny::includeCSS(system.file("style.css", package = "regexplain")),
  8. gadgetTitleBar(
  9. "regexplain",
  10. right = miniTitleBarButton("done", "To Console", TRUE)
  11. ),
  12. miniTabstripPanel(
  13. selected = if (is.null(text)) "Text" else "Regex",
  14. miniTabPanel(
  15. "Text", icon = icon('file-text-o'),
  16. miniContentPanel(
  17. fillCol(
  18. flex = c(3, 1),
  19. textAreaInputAlt('text', label = "Text", value = paste(text, collapse = "\n"), resize = "both", width = "100%", height="90%"),
  20. inputPanel(
  21. checkboxInput('text_break_newline', "Break Lines", TRUE)
  22. )
  23. )
  24. )
  25. ),
  26. miniTabPanel(
  27. "Regex", icon = icon('terminal'),
  28. miniContentPanel(
  29. textInputCode('pattern', 'Regex', width = "100%",
  30. placeholder = "Enter regex, double backslash not required"),
  31. htmlOutput('result')
  32. )
  33. ),
  34. miniTabPanel(
  35. "Help", icon = icon("support"),
  36. miniContentPanel(
  37. tags$p("Help will go here.")
  38. )
  39. )
  40. )
  41. )
  42. server <- function(input, output, session) {
  43. rtext <- reactive({
  44. x <- if (input$text_break_newline) {
  45. strsplit(input$text, "\n")[[1]]
  46. } else input$text
  47. x
  48. })
  49. output$result <- renderUI({
  50. if (is.null(rtext())) return(NULL)
  51. if (input$pattern == "") {
  52. return(toHTML(paste('<p class="results">', rtext(), "</p>", collapse = "")))
  53. }
  54. tryCatch({
  55. toHTML(
  56. paste(
  57. view_regex(rtext(), sanitize_text_input(input$pattern), render = FALSE),
  58. collapse = ""
  59. )
  60. )
  61. },
  62. error = function(e) {
  63. toHTML(paste0("<pre class='alert alert-danger' style='padding: 4px; margin-top: 1px; margin-bottom: 4px;'>", paste(e$message, collapse = "<br>"), "</pre>"),
  64. paste('<p class="results">', rtext(), "</p>", collapse = ""))
  65. })
  66. })
  67. observeEvent(input$done, {
  68. # browser()
  69. if (input$pattern != "") {
  70. pattern <- paste0('regex <- "', escape_backslash(sanitize_text_input(input$pattern)), '"')
  71. rstudioapi::sendToConsole(pattern, FALSE)
  72. }
  73. stopApp()
  74. })
  75. observeEvent(input$cancel, {
  76. stopApp()
  77. })
  78. }
  79. viewer <- shiny::paneViewer(700)
  80. runGadget(ui, server, viewer = viewer)
  81. }
  82. sanitize_text_input <- function(x) {
  83. x <- gsub("(“|”)", '"', x)
  84. x <- gsub("‘|’", "'", x)
  85. x
  86. }
  87. toHTML <- function(...) {
  88. x <- paste(..., collapse = "")
  89. x <- gsub("\n", "\\\\n", x)
  90. HTML(x)
  91. }
  92. # ---- Modified Shiny Inputs ----
  93. #' Modified Text Area Input
  94. #'
  95. #' @inheritParams shiny textAreaInput
  96. textAreaInputAlt <- function(inputId, label, value = "", width = NULL, height = NULL,
  97. cols = NULL, rows = NULL, placeholder = NULL, resize = NULL,
  98. is_code = TRUE) {
  99. `%AND%` <- shiny:::`%AND%`
  100. value <- shiny::restoreInput(id = inputId, default = value)
  101. if (!is.null(resize)) {
  102. resize <- match.arg(resize, c("both", "none", "vertical", "horizontal"))
  103. }
  104. style <- paste(
  105. if (!is.null(width)) paste0("width: ", shiny::validateCssUnit(width), ";"),
  106. if (!is.null(height)) paste0("height: ", shiny::validateCssUnit(height), ";"),
  107. if (!is.null(resize)) paste0("resize: ", resize, ";"),
  108. if (is_code) 'font-family: "Monaco", "Inconsolata", monospace;'
  109. )
  110. parent_style <- paste(
  111. if (!is.null(width) && grepl("%", width)) paste0("width: ", width, ";"),
  112. if (!is.null(height) && grepl("%", height)) paste0("height: ", height, ";")
  113. )
  114. # Workaround for tag attribute=character(0) bug:
  115. # https://github.com/rstudio/htmltools/issues/65
  116. if (length(style) == 0) style <- NULL
  117. shiny::div(class = "form-group shiny-input-container",
  118. label %AND% shiny::tags$label(label, `for` = inputId),
  119. style = if (!parent_style %in% c(" ", "", " ")) parent_style,
  120. shiny::tags$textarea(
  121. id = inputId,
  122. class = "form-control",
  123. placeholder = placeholder,
  124. style = style,
  125. rows = rows,
  126. cols = cols,
  127. autocomplete = "off",
  128. autocorrect = "off",
  129. autocapitalize = "off",
  130. spellcheck = "false",
  131. value
  132. )
  133. )
  134. }
  135. #' Modified Text Input
  136. #'
  137. #' @inheritParams shiny textInput
  138. textInputCode <- function(inputId, label, value = "", width = NULL,
  139. placeholder = NULL) {
  140. `%AND%` <- shiny:::`%AND%`
  141. value <- shiny::restoreInput(id = inputId, default = value)
  142. shiny::div(class = "form-group shiny-input-container",
  143. style = if (!is.null(width)) paste0("width: ", shiny::validateCssUnit(width), ";"),
  144. label %AND% shiny::tags$label(label, `for` = inputId),
  145. shiny::tags$input(id = inputId, type="text", class="form-control", value=value,
  146. style = 'font-family: "Monaco", "Inconsolata", monospace;',
  147. autocomplete = "off", autocorrect = "off",
  148. autocapitalize = "off", spellcheck = "false",
  149. placeholder = placeholder)
  150. )
  151. }