Skip to content

Commit

Permalink
Merge pull request #101 from Appsilon/configurable-glue-delimiters
Browse files Browse the repository at this point in the history
Custom glue delimiters. Small bug fix literal braces with parseable braces.
  • Loading branch information
radbasa authored Jun 3, 2024
2 parents 309e858 + 2b6acf5 commit ea0aaa8
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 2 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: box.linters
Title: Linters for 'box' Modules
Version: 0.9.0.9006
Version: 0.9.0.9007
Authors@R:
c(
person("Ricardo Rodrigo", "Basa", role = c("aut", "cre"), email = "[email protected]"),
Expand Down
10 changes: 9 additions & 1 deletion R/get_objects_in_strings.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ get_objects_in_strings <- function(xml) {
"

all_strings <- extract_xml_and_text(xml, xpath_str_consts)

glue_open <- getOption("glue.open", default = "\\{")
glue_close <- getOption("glue.close", default = "\\}")

all_strings$text <- gsub(glue_open, "{", all_strings$text)
all_strings$text <- gsub(glue_close, "}", all_strings$text)

text_between_braces <- stringr::str_match_all(all_strings$text, "(\\{(?:\\{??[^\\{]*?\\}))")

tryCatch({
Expand All @@ -22,7 +29,8 @@ get_objects_in_strings <- function(xml) {
return(NULL)
}

parsed_code <- parse(text = each_text[, 2], keep.source = TRUE)
text_to_parse <- each_text[substr(each_text[, 2], 1, 2) != "{{", 2]
parsed_code <- parse(text = text_to_parse, keep.source = TRUE)
xml_parsed_code <- xml2::read_xml(xmlparsedata::xml_parse_data(parsed_code))
objects_called <- get_object_calls(xml_parsed_code)
functions_calls <- get_function_calls(xml_parsed_code)
Expand Down
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,26 @@ Or, use `box.linters` from within a `{rhino}` project:
rhino::lint_r()
```

## {glue} String Interpolation

`{box.linters}` also looks inside `{glue}` strings. The default opening and closing delimiters are "`{`" and "`}`". `{glue}` provides a way to [customize delimiters](https://glue.tidyverse.org/reference/glue.html). Support for custom `{glue}` delimiters are provided *project-wide* by setting `glue.open` and `glue.close` options in the following manner:

```r
options(
list(
glue.open = "<<",
glue.close = ">>"
)
)
```

This is consistent with [`glue::glue()`](https://glue.tidyverse.org/reference/glue.html), doubling the full delimiter escapes it.

Because setting `glue.open` and `glue.close` will be *global* or *project-wide*, it is advised to invoke `glue` in the following manner to avoid confusion:

```r
glue::glue(..., .open = getOption("glue.open"), .close = getOption("glue.close"))
```

## Contribute

Expand Down
62 changes: 62 additions & 0 deletions tests/testthat/test-get_objects_in_strings.R
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@ test_that("get_objects_in_strings ignores literal glue objects {{ }}", {
expect_equal(results, NULL)
})

test_that("get_objects_in_strings ignores literal glue objects {{ }} mixed in with { }", {
code <- "
string <- \"Some {{value_a + 1}} in a {value_b} string.\"
"
xml_code <- code_to_xml_expr(code)
results <- get_objects_in_strings(xml_code)
should_find <- "value_b"

expect_equal(results, should_find)
})

test_that("get_objects_in_strings extracts objects from multiline code", {
code <- "
string <- \"Some text {
Expand Down Expand Up @@ -128,3 +139,54 @@ test_that("get_objects_in_strings handles multiple string constants in code", {

expect_setequal(results, should_find)
})

test_that("get_objects_in_strings handles custom glue .open and .close symbols", {
withr::with_options(
list(
glue.open = "<<",
glue.close = ">>"
),
{
code <- "
string <- \"Some <<value_a>> and <<value_b>> in a string.\"
"
xml_code <- code_to_xml_expr(code)
results <- get_objects_in_strings(xml_code)
should_find <- c("value_a", "value_b")

expect_setequal(results, should_find)

code <- "
string <- \"Some <<value_a>> and <value_b> in a string.\"
"
xml_code <- code_to_xml_expr(code)
results <- get_objects_in_strings(xml_code)
should_find <- c("value_a")

expect_setequal(results, should_find)

code <- "
string <- \"Some <<value_a>> and <<<<value_b>>>> in a string.\"
"
xml_code <- code_to_xml_expr(code)
results <- get_objects_in_strings(xml_code)
should_find <- c("value_a")

expect_setequal(results, should_find)

code <- "
string <- \"Some text <<
{
internal_var <- external_var
some_function_call(internal_var, another_external_var)
}
>> here.\"
"
xml_code <- code_to_xml_expr(code)
results <- get_objects_in_strings(xml_code)
should_find <- c("external_var", "some_function_call", "internal_var", "another_external_var")

expect_setequal(results, should_find)
}
)
})

0 comments on commit ea0aaa8

Please sign in to comment.