| @@ -0,0 +1,3 @@ | |||
| ^.*\.Rproj$ | |||
| ^\.Rproj\.user$ | |||
| ^LICENSE\.md$ | |||
| @@ -0,0 +1,3 @@ | |||
| .Rproj.user | |||
| .Rhistory | |||
| .RData | |||
| @@ -0,0 +1,19 @@ | |||
| Package: regexhelp | |||
| Title: Rstudio addin to help you with your regexes (in progress) | |||
| Version: 0.0.0.9000 | |||
| Date: 2018-03-07 | |||
| Authors@R: person("Garrick", "Aden-Buie", email = "g.adenbuie@gmail.com", role = c("aut", "cre")) | |||
| Description: Test and view regexes. | |||
| Depends: | |||
| R (>= 3.4.3), | |||
| dplyr | |||
| License: MIT + file LICENSE | |||
| Encoding: UTF-8 | |||
| LazyData: true | |||
| Imports: | |||
| purrr, | |||
| rmarkdown, | |||
| utils, | |||
| tidyr, | |||
| rstudioapi | |||
| RoxygenNote: 6.0.1 | |||
| @@ -0,0 +1,2 @@ | |||
| YEAR: 2018 | |||
| COPYRIGHT HOLDER: Garrick Aden-Buie | |||
| @@ -0,0 +1,21 @@ | |||
| # MIT License | |||
| Copyright (c) 2018 Garrick Aden-Buie | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| of this software and associated documentation files (the "Software"), to deal | |||
| in the Software without restriction, including without limitation the rights | |||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
| copies of the Software, and to permit persons to whom the Software is | |||
| furnished to do so, subject to the following conditions: | |||
| The above copyright notice and this permission notice shall be included in all | |||
| copies or substantial portions of the Software. | |||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| SOFTWARE. | |||
| @@ -0,0 +1,4 @@ | |||
| # Generated by roxygen2: do not edit by hand | |||
| export(run_regex) | |||
| export(view_regex) | |||
| @@ -0,0 +1,102 @@ | |||
| #' @export | |||
| run_regex <- function( | |||
| text, | |||
| pattern, | |||
| ignore.case = FALSE, | |||
| perl = FALSE, | |||
| fixed = FALSE, | |||
| useBytes = FALSE, | |||
| invert = FALSE | |||
| ) { | |||
| m <- regexec(pattern, text, ignore.case, perl, fixed, useBytes) | |||
| x <- purrr::map(purrr::set_names(m, text), function(mi) list('idx' = purrr::map2(mi, attr(mi, "match.length"), ~ if(.x[1] != -1) c(.x, .x + .y - 1L)))) | |||
| y <- purrr::map(purrr::set_names(text), ~ list(text = .)) | |||
| z <- purrr::map(purrr::set_names(regmatches(text, m), text), ~ list(m = .)) | |||
| x <- utils::modifyList(y, x, TRUE) | |||
| utils::modifyList(z, x, TRUE) | |||
| } | |||
| wrap_span <- function(x, escape = FALSE) { | |||
| if (is.null(x$idx[[1]])) return(x$text) | |||
| text <- x$text | |||
| idx <- x$idx | |||
| len_idx <- length(idx) | |||
| inserts <- data.frame( | |||
| i = 1:len_idx - 1, | |||
| start = purrr::map_int(idx, ~ .[1]), | |||
| end = purrr::map_int(idx, ~ .[2]) + 1 | |||
| ) %>% | |||
| mutate( | |||
| class = sprintf("group g%02d", i), | |||
| pad = 0 | |||
| ) | |||
| for (j in seq_len(nrow(inserts))) { | |||
| if (inserts$i[j] == 0) next | |||
| overlap <- filter( | |||
| inserts, | |||
| i != 0, | |||
| start <= !!inserts$start[j] & end > !!inserts$end[j]) | |||
| inserts[j, 'pad'] <- inserts$pad[j] + nrow(overlap) | |||
| } | |||
| inserts <- inserts %>% | |||
| tidyr::gather(type, loc, start:end) %>% | |||
| mutate( | |||
| class = ifelse(pad > 0, sprintf("%s pad%02d", class, pad), class), | |||
| insert = ifelse(type == 'start', sprintf('<span class="%s">', class), "</span>") | |||
| ) %>% | |||
| group_by(loc, type) %>% | |||
| summarize(insert = paste(insert, collapse = '')) | |||
| idx_split <- c(0 - (inserts$loc[1] == 0), inserts$loc) | |||
| if (!(nchar(text) + 1) %in% idx_split) idx_split <- c(idx_split, nchar(text) + 1) | |||
| text_split <- c() | |||
| for (k in seq_along(idx_split[-1])) { | |||
| text_split <- c(text_split, substr(text, idx_split[k], idx_split[k+1] - 1)) | |||
| } | |||
| out <- c() | |||
| for (j in seq_along(text_split)) { | |||
| out <- c( | |||
| out, | |||
| ifelse(escape, escape_html(text_split[j]), text_split[j]), | |||
| if (!is.na(inserts$insert[j])) inserts$insert[j] | |||
| ) | |||
| } | |||
| paste(out, collapse = '') | |||
| } | |||
| #' View grouped regex results | |||
| #' | |||
| #' @param text Text to search | |||
| #' @param pattern Regex pattern to look for | |||
| #' @param render Render results to an HTML doc and open in RStudio viewer? | |||
| #' @param escape Escape HTML-related characters in `text`? | |||
| #' @param knitr Print into knitr doc? If `TRUE`, marks text as `asis_output` and | |||
| #' sets `render = FALSE` and `escape = TRUE`. | |||
| #' @param ... Passed to [run_regex] | |||
| #' @export | |||
| view_regex <- function(text, pattern, ..., render = TRUE, escape = render, knitr = FALSE) { | |||
| if (knitr) { | |||
| render <- FALSE | |||
| escape <- TRUE | |||
| } | |||
| res <- run_regex(text, pattern, ...) | |||
| res <- purrr::map_chr(res, wrap_span, escape = escape) | |||
| res <- paste("<p class='results'>", res, "</p>") | |||
| if (knitr) return(knitr::asis_output(res)) | |||
| if (!render) return(res) | |||
| head <- c( | |||
| "---", "pagetitle: View Regex", "---", | |||
| "<h5>Regex</h5>", | |||
| "<p><pre>", escape_html(pattern), "</pre></p>", | |||
| "<h5>Results</h5>" | |||
| ) | |||
| res <- c(head, res) | |||
| tmp <- tempfile(fileext = ".Rmd") | |||
| cat(res, file = tmp, sep = "\n") | |||
| tmp_html <- suppressWarnings( | |||
| rmarkdown::render( | |||
| tmp, | |||
| output_format = rmarkdown::html_document(css = system.file('style.css', package='regexhelp')), | |||
| quiet = TRUE | |||
| )) | |||
| rstudioapi::viewer(tmp_html) | |||
| } | |||
| @@ -0,0 +1,7 @@ | |||
| escape_html <- function(x) { | |||
| x = gsub("&", "&", x) | |||
| x = gsub("<", "<", x) | |||
| x = gsub(">", ">", x) | |||
| x = gsub("\"", """, x) | |||
| x | |||
| } | |||
| @@ -0,0 +1,87 @@ | |||
| .results { | |||
| font-family: "Monaco", "Inconsolata", monospace; | |||
| padding-top: 5px; | |||
| } | |||
| .group { | |||
| border-bottom: 2px solid; | |||
| padding: 0px; | |||
| } | |||
| .g00 { | |||
| padding: 1px; | |||
| background-color: #f0f0f0; | |||
| border: 1px solid #b0b0b0; | |||
| border-left: 1px solid #b0b0b0; | |||
| border-right: 1px solid #b0b0b0; | |||
| border-top: 1px solid #b0b0b0; | |||
| } | |||
| .g01 { | |||
| border-color: green; | |||
| color: green; | |||
| } | |||
| .g02 { | |||
| border-color: blue; | |||
| color: blue; | |||
| } | |||
| .g03 { | |||
| border-color: red; | |||
| color: red; | |||
| } | |||
| .g04 { | |||
| border-color: orange; | |||
| color: orange; | |||
| } | |||
| .g05 { | |||
| border-color: purple; | |||
| color: purple; | |||
| } | |||
| .g06 { | |||
| border-color: DeepPink; | |||
| color: DeepPink; | |||
| } | |||
| .g07 { | |||
| border-color: Tomato; | |||
| color: Tomato; | |||
| } | |||
| .g08 { | |||
| border-color: DarkSeaGreen; | |||
| color: DarkSeaGreen; | |||
| } | |||
| .g09 { | |||
| border-color: DeepSkyBlue; | |||
| color: DeepSkyBlue; | |||
| } | |||
| .g10 { | |||
| border-color: Sienna; | |||
| color: Sienna; | |||
| } | |||
| .pad01 { | |||
| padding-bottom: 3px; | |||
| } | |||
| .pad02 { | |||
| padding-bottom: 6px; | |||
| } | |||
| .pad03 { | |||
| padding-bottom: 9px; | |||
| } | |||
| .pad04 { | |||
| padding-bottom: 12px; | |||
| } | |||
| .pad05 { | |||
| padding-bottom: 15px; | |||
| } | |||
| .pad06 { | |||
| padding-bottom: 18px; | |||
| } | |||
| @@ -0,0 +1,26 @@ | |||
| % Generated by roxygen2: do not edit by hand | |||
| % Please edit documentation in R/run_regex.R | |||
| \name{view_regex} | |||
| \alias{view_regex} | |||
| \title{View grouped regex results} | |||
| \usage{ | |||
| view_regex(text, pattern, ..., render = TRUE, escape = render, | |||
| knitr = FALSE) | |||
| } | |||
| \arguments{ | |||
| \item{text}{Text to search} | |||
| \item{pattern}{Regex pattern to look for} | |||
| \item{...}{Passed to [run_regex]} | |||
| \item{render}{Render results to an HTML doc and open in RStudio viewer?} | |||
| \item{escape}{Escape HTML-related characters in `text`?} | |||
| \item{knitr}{Print into knitr doc? If `TRUE`, marks text as `asis_output` and | |||
| sets `render = FALSE` and `escape = TRUE`.} | |||
| } | |||
| \description{ | |||
| View grouped regex results | |||
| } | |||
| @@ -0,0 +1,21 @@ | |||
| Version: 1.0 | |||
| RestoreWorkspace: No | |||
| SaveWorkspace: No | |||
| AlwaysSaveHistory: Default | |||
| EnableCodeIndexing: Yes | |||
| UseSpacesForTab: Yes | |||
| NumSpacesForTab: 2 | |||
| Encoding: UTF-8 | |||
| RnwWeave: Sweave | |||
| LaTeX: XeLaTeX | |||
| AutoAppendNewline: Yes | |||
| StripTrailingWhitespace: Yes | |||
| BuildType: Package | |||
| PackageUseDevtools: Yes | |||
| PackageInstallArgs: --no-multiarch --with-keep.source | |||
| PackageRoxygenize: rd,collate,namespace | |||