Skip to content

Commit

Permalink
chore: CRAN v1.0.1 re-submission
Browse files Browse the repository at this point in the history
  • Loading branch information
trevorld committed Aug 7, 2019
1 parent 13ace09 commit 19d4301
Show file tree
Hide file tree
Showing 10 changed files with 223 additions and 106 deletions.
2 changes: 2 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
^cran-comments.rst$
^README.Rmd$
^README.html$
^Rakefile$
^notes.txt$
^LICENSE.md$
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
README.html
*.swp
notes.txt
6 changes: 3 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
Package: bracer
Title: Bash-style Brace Expansion
Version: 0.1.0-0
Title: Brace Expansions
Version: 1.0.1
Authors@R:
person(given = "Trevor",
family = "Davis",
role = c("aut", "cre"),
email = "[email protected]")
Description: Provides partial support for Bash-style brace expansions.
Description: Performs brace expansions on strings. Made popular by Unix shells, brace expansion allows users to quickly generate certain character vectors by taking a single string and (recursively) expanding the comma-separated lists and double-period-separated integer and character sequences enclosed within braces in that string. The double-period-separated numeric integer expansion also supports padding the resulting numbers with zeros.
Imports: stringr
License: MIT + file LICENSE
Encoding: UTF-8
Expand Down
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
bracer 1.0.1
============

* ``expand_braces`` can now parse nested braces.

bracer 0.1
==========

Expand Down
109 changes: 84 additions & 25 deletions R/expand.R
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
#' Bash-style brace expansion
#'
#' \code{expand_braces} provides partial support for
#' Bash-style brace expansion.
#' \code{expand_braces} performs brace expansions on strings. Made popular by Unix shells, brace expansion allows users to quickly generate certain character vectors by taking a single string and (recursively) expanding the comma-separated lists and double-period-separated integer and character sequences enclosed within braces in that string. The double-period-separated numeric integer expansion also supports padding the resulting numbers with zeros.

#' @param string input character vector
#' @return A character vector
#' @examples
#' expand_braces("Foo{A..F}")
#' expand_braces("Foo{01..10}")
#' expand_braces("Foo{A..F}{1..5..2}")
#' expand_braces("Foo{a..f..2}{-01..5}")
#' expand_braces("Foo{A..E..2}{1..5..2}")
#' expand_braces("Foo{-01..1}")
#' expand_braces("Foo{{d..d},{bar,biz}}.{py,bash}")
#' @import stringr
#' @export
expand_braces <- function(string) {
# Find brace starts and ends
brace_token <- "(?<!\\\\)\\{([^}]|\\\\\\})*(?<!\\\\)\\}"
locations <- str_locate_all(string, brace_token)[[1]]
expand_braces_helper(string)
}
brace_token <- "(?<!\\\\)\\{([^}]|\\\\\\})*(?<!\\\\)\\}"
has_brace <- function(string) {
str_detect(string, brace_token)
}

expand_braces_helper <- function(string, process=TRUE) {
locations <- get_locations(string) # Find brace starts and ends
n <- nrow(locations)
if (n == 0) return(process_string(string))
braced <- vector("list", n)
Expand All @@ -30,9 +37,43 @@ expand_braces <- function(string) {

df <- expand.grid(rev(braced), stringsAsFactors=FALSE)
value <- preamble
for (ii in seq(n))
for (ii in seq(n)) {
value <- paste0(value, df[,n+1-ii], non_braced[ii])
process_string(value)
}
if (process) {
process_string(value)
} else {
value
}
}

data_frame <- function(...) { data.frame(..., stringsAsFactors=FALSE) }

# get locations of top level braces
get_locations <- function(string) {
left_brace <- "(?<!\\\\)\\{"
left_locations <- str_locate_all(string, left_brace)[[1]]
if(nrow(left_locations)==0) { return(matrix(numeric(0), ncol=2)) }
df_left <- data_frame(index=left_locations[,1], char="{")
right_brace <- "(?<!\\\\)\\}"
right_locations <- str_locate_all(string, right_brace)[[1]]
if(nrow(right_locations)==0) { return(matrix(numeric(0), ncol=2)) }
df_right <- data_frame(index=right_locations[,1], char="}")
df <- rbind(df_left, df_right)
df <- df[order(df$index),]
df$level <- 0
level <- 1
for (ii in seq(length=nrow(df))) {
if (df[ii,2]=="{") {
df[ii,3] <- level
level <- level + 1
} else {
level <- level - 1
df[ii,3] <- level
}
}
df <- df[which(df$level==1),]
matrix(df$index, ncol=2, byrow=TRUE)
}

zero_pad <- function(numbers, width=2) {
Expand All @@ -54,18 +95,29 @@ expand_brace <- function(string, locations, i) {
il <- locations[i,1]
ir <- locations[i,2]
brace <- str_sub(string, il, ir)
if (str_detect(brace, "(?<!\\\\),")) { # comma split
expand_comma(brace)
} else if (str_detect(brace, "\\.{2}")) {
expand_periods(brace)
inner <- str_sub(brace, 2, -2)
if (has_comma(inner)) {
expand_comma(inner)
} else if (has_periods(inner)) {
expand_periods(inner)
} else if (has_brace(inner)) {
paste0("{", expand_braces_helper(inner, FALSE), "}")
} else {
brace
}
}

comma_token <- "(?<!\\\\),(?![^\\{]*\\})"
# comma_token <- "(?<!\\\\),(?![^\\{]*[^\\\\]\\})"
has_comma <- function(string) {
str_detect(string, comma_token)
}

expand_comma <- function(string) {
string <- str_sub(string, 2, -2)
str_split(string, "(?<!\\\\),")[[1]]
elements <- str_split(string, comma_token)[[1]]
elements <- lapply(elements, expand_braces_helper, FALSE)
elements <- c(elements, recursive=TRUE)
elements
}

ASCII <- c(" ", "!", '"', "#", "$", "%", "&", "'", "(", ")", "*", "+", ",",
Expand All @@ -76,20 +128,28 @@ has_pad <- function(digits) {
any(str_detect(digits[1:2], "^-?0[0-9]+"))
}

alpha2_token <- "^[[:alpha:]]\\.{2}[[:alpha:]]$"
alpha3_token <- "^[[:alpha:]]\\.{2}[[:alpha:]]\\.{2}-?[[:digit:]]+$"
digit2_token <- "^-?[[:digit:]]+\\.{2}-?[[:digit:]]+$"
digit3_token <- "^-?[[:digit:]]+\\.{2}-?[[:digit:]]+\\.{2}-?[[:digit:]]+$"
period_token <- paste(alpha2_token, alpha3_token, digit2_token, digit3_token, sep="|")

has_periods <- function(string) {
str_detect(string, period_token)
}

expand_periods <- function(string) {
if (str_detect(string, "\\{[[:alpha:]]\\.{2}[[:alpha:]]\\}")) {
i_left <- match(str_sub(string, 2, 2), ASCII)
i_right <- match(str_sub(string, 5, 5), ASCII)
if (str_detect(string, alpha2_token)) {
i_left <- match(str_sub(string, 1, 1), ASCII)
i_right <- match(str_sub(string, 4, 4), ASCII)
ASCII[i_left:i_right]
} else if (str_detect(string, "\\{[[:alpha:]]\\.{2}[[:alpha:]]\\.{2}-?[[:digit:]]+\\}")) {
string <- str_sub(string, 2, -2)
} else if (str_detect(string, alpha3_token)) {
items <- str_split(string, "\\.{2}")[[1]]
i_left <- match(items[1], ASCII)
i_right <- match(items[2], ASCII)
by <- sign(i_right-i_left)*abs(as.numeric(items[3]))
ASCII[seq(i_left,i_right,by)]
} else if (str_detect(string, "\\{-?[[:digit:]]+\\.{2}-?[[:digit:]]+\\}")) {
string <- str_sub(string, 2, -2)
} else if (str_detect(string, digit2_token)) {
digits <- str_split(string, "\\.{2}")[[1]]
numbers <- as.numeric(digits)
values <- seq(numbers[1], numbers[2])
Expand All @@ -98,8 +158,7 @@ expand_periods <- function(string) {
} else {
values
}
} else if (str_detect(string, "\\{-?[[:digit:]]+\\.{2}-?[[:digit:]]+\\.{2}-?[[:digit:]]+\\}")) {
string <- str_sub(string, 2, -2)
} else if (str_detect(string, digit3_token)) {
digits <- str_split(string, "\\.{2}")[[1]]
numbers <- as.numeric(digits)
by <- sign(numbers[2]-numbers[1])*abs(numbers[3])
Expand All @@ -110,7 +169,7 @@ expand_periods <- function(string) {
values
}
} else {
string
paste0("{", string, "}")
}
}

Expand Down
28 changes: 18 additions & 10 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,35 @@ bracer
[![Travis-CI Build Status](https://travis-ci.org/trevorld/bracer.png?branch=master)](https://travis-ci.org/trevorld/bracer)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/trevorld/bracer?branch=master&svg=true)](https://ci.appveyor.com/project/trevorld/bracer)
[![Coverage Status](https://img.shields.io/codecov/c/github/trevorld/bracer/master.svg)](https://codecov.io/github/trevorld/bracer?branch=master)
[![Project Status: WIPInitial development is in progress, but there has not yet been a stable, usable release suitable for the public.](https://www.repostatus.org/badges/latest/wip.svg)](https://www.repostatus.org/#wip)
[![Project Status: InactiveThe project has reached a stable, usable state but is no longer being actively developed; support/maintenance will be provided as time allows.](https://www.repostatus.org/badges/latest/inactive.svg)](https://www.repostatus.org/#inactive)

``bracer`` provides partial support for [Bash-style brace expansion](https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Brace-Expansion) in R.
``bracer`` provides support for performing [brace expansions](https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Brace-Expansion) on strings in R.

```{r examples}
library("bracer")
expand_braces("Foo{A..F}")
expand_braces("Foo{01..10}")
expand_braces("Foo{A..F}{1..5..2}")
expand_braces("Foo{a..f..2}{-01..5}")
expand_braces("Foo{A..E..2}{1..5..2}")
expand_braces("Foo{-01..1}")
expand_braces("Foo{{d..d},{bar,biz}}.{py,bash}")
```

To install the developmental version use the following commands in R:
To install the release version on CRAN use the following command in R:

```{r install_stable, eval=FALSE}
install.packages("bracer")
```

To install the developmental version use the following command in R:

```{r install, eval=FALSE}
remotes::install_github("trevorld/bracer")
```

``bracer`` currently does not properly support the proper Bash-style brace expansion under several conditions such as:
``bracer`` currently does not properly support the "correct" (Bash-style) brace expansion under several edge conditions such as:

1. Nested braces e.g. ``{{a..d},{1..2}}``
2. Unbalanced braces e.g. ``{a,d}}``
3. Using quotes to escape terms e.g. ``{'a,b','c'}``
4. Including a non-escaping backslash ahead of a brace or comma e.g. ``{a,b\\\\\\\\}}``
1. Unbalanced braces e.g. ``{a,d}}``
2. Using surrounding quotes to escape terms e.g. ``{'a,b','c'}``
3. Escaped *inner* braces e.g. ``{a,b\\}c,d}``
4. (Non-escaping) backslashes before braces e.g. ``{a,\\\\{a,b}c}'``
5. Sequences from letters to non-letter ASCII characters e.g. ``X{a..#}X``
45 changes: 29 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ bracer
[![Travis-CI Build Status](https://travis-ci.org/trevorld/bracer.png?branch=master)](https://travis-ci.org/trevorld/bracer)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/trevorld/bracer?branch=master&svg=true)](https://ci.appveyor.com/project/trevorld/bracer)
[![Coverage Status](https://img.shields.io/codecov/c/github/trevorld/bracer/master.svg)](https://codecov.io/github/trevorld/bracer?branch=master)
[![Project Status: WIPInitial development is in progress, but there has not yet been a stable, usable release suitable for the public.](https://www.repostatus.org/badges/latest/wip.svg)](https://www.repostatus.org/#wip)
[![Project Status: InactiveThe project has reached a stable, usable state but is no longer being actively developed; support/maintenance will be provided as time allows.](https://www.repostatus.org/badges/latest/inactive.svg)](https://www.repostatus.org/#inactive)

``bracer`` provides partial support for [Bash-style brace expansion](https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Brace-Expansion) in R.
``bracer`` provides support for performing [brace expansions](https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Brace-Expansion) on strings in R.


```r
Expand All @@ -28,35 +28,48 @@ expand_braces("Foo{01..10}")
```

```r
expand_braces("Foo{A..F}{1..5..2}")
expand_braces("Foo{A..E..2}{1..5..2}")
```

```
## [1] "FooA1" "FooA3" "FooA5" "FooB1" "FooB3" "FooB5" "FooC1" "FooC3"
## [9] "FooC5" "FooD1" "FooD3" "FooD5" "FooE1" "FooE3" "FooE5" "FooF1"
## [17] "FooF3" "FooF5"
## [1] "FooA1" "FooA3" "FooA5" "FooC1" "FooC3" "FooC5" "FooE1" "FooE3" "FooE5"
```

```r
expand_braces("Foo{a..f..2}{-01..5}")
expand_braces("Foo{-01..1}")
```

```
## [1] "Fooa-01" "Fooa000" "Fooa001" "Fooa002" "Fooa003" "Fooa004" "Fooa005"
## [8] "Fooc-01" "Fooc000" "Fooc001" "Fooc002" "Fooc003" "Fooc004" "Fooc005"
## [15] "Fooe-01" "Fooe000" "Fooe001" "Fooe002" "Fooe003" "Fooe004" "Fooe005"
## [1] "Foo-01" "Foo000" "Foo001"
```

To install the developmental version use the following commands in R:
```r
expand_braces("Foo{{d..d},{bar,biz}}.{py,bash}")
```

```
## [1] "Food.py" "Food.bash" "Foobar.py" "Foobar.bash" "Foobiz.py"
## [6] "Foobiz.bash"
```

To install the release version on CRAN use the following command in R:


```r
install.packages("bracer")
```

To install the developmental version use the following command in R:


```r
remotes::install_github("trevorld/bracer")
```

``bracer`` currently does not properly support the proper Bash-style brace expansion under several conditions such as:
``bracer`` currently does not properly support the "correct" (Bash-style) brace expansion under several edge conditions such as:

1. Nested braces e.g. ``{{a..d},{1..2}}``
2. Unbalanced braces e.g. ``{a,d}}``
3. Using quotes to escape terms e.g. ``{'a,b','c'}``
4. Including a non-escaping backslash ahead of a brace or comma e.g. ``{a,b\\\\\\\\}}``
1. Unbalanced braces e.g. ``{a,d}}``
2. Using surrounding quotes to escape terms e.g. ``{'a,b','c'}``
3. Escaped *inner* braces e.g. ``{a,b\\}c,d}``
4. (Non-escaping) backslashes before braces e.g. ``{a,\\\\{a,b}c}'``
5. Sequences from letters to non-letter ASCII characters e.g. ``X{a..#}X``
14 changes: 14 additions & 0 deletions cran-comments.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Resubmission. Elaborated the 'Description' field as requested.

**Test environments**

* local (linux, R 3.4.4)
* win-builder (windows, R devel)
* appveyor (windows, R devel)
* appveyor (windows, R release)
* travis-ci (linux, R devel)
* travis-ci (linux, R release)

**R CMD check --as-cran results**

Status: 1 NOTE (that this is a new submission)
8 changes: 4 additions & 4 deletions man/expand_braces.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 19d4301

Please sign in to comment.