Title: | Interpreted String Literals |
---|---|
Description: | An implementation of interpreted string literals, inspired by Python's Literal String Interpolation <https://www.python.org/dev/peps/pep-0498/> and Docstrings <https://www.python.org/dev/peps/pep-0257/> and Julia's Triple-Quoted String Literals <https://docs.julialang.org/en/v1.3/manual/strings/#Triple-Quoted-String-Literals-1>. |
Authors: | Jim Hester [aut] , Jennifer Bryan [aut, cre] , Posit Software, PBC [cph, fnd] |
Maintainer: | Jennifer Bryan <[email protected]> |
License: | MIT + file LICENSE |
Version: | 1.8.0.9000 |
Built: | 2024-11-03 06:07:03 UTC |
Source: | https://github.com/tidyverse/glue |
A glue object is a character vector with S3 class "glue"
. The "glue"
class implements a print method that shows the literal contents (rather than
the string implementation) and a +
method, so that you can concatenate with
the addition operator.
as_glue(x, ...)
as_glue(x, ...)
x |
object to be coerced. |
... |
further arguments passed to methods. |
A character vector with S3 class "glue"
.
x <- as_glue(c("abc", "\"\\\\", "\n")) x x <- 1 y <- 3 glue("x + y") + " = {x + y}"
x <- as_glue(c("abc", "\"\\\\", "\n")) x x <- 1 y <- 3 glue("x + y") + " = {x + y}"
Expressions enclosed by braces will be evaluated as R code. Long strings are broken by line and concatenated together. Leading whitespace and blank lines from the first and last lines are automatically trimmed.
glue_data( .x, ..., .sep = "", .envir = parent.frame(), .open = "{", .close = "}", .na = "NA", .null = character(), .comment = "#", .literal = FALSE, .transformer = identity_transformer, .trim = TRUE ) glue( ..., .sep = "", .envir = parent.frame(), .open = "{", .close = "}", .na = "NA", .null = character(), .comment = "#", .literal = FALSE, .transformer = identity_transformer, .trim = TRUE )
glue_data( .x, ..., .sep = "", .envir = parent.frame(), .open = "{", .close = "}", .na = "NA", .null = character(), .comment = "#", .literal = FALSE, .transformer = identity_transformer, .trim = TRUE ) glue( ..., .sep = "", .envir = parent.frame(), .open = "{", .close = "}", .na = "NA", .null = character(), .comment = "#", .literal = FALSE, .transformer = identity_transformer, .trim = TRUE )
.x |
[ |
... |
[ For |
.sep |
[ |
.envir |
[ |
.open |
[ |
.close |
[ |
.na |
[ |
.null |
[ |
.comment |
[ |
.literal |
[ |
.transformer |
[ |
.trim |
[ |
A glue object, as created by as_glue()
.
https://www.python.org/dev/peps/pep-0498/ and https://www.python.org/dev/peps/pep-0257/ upon which this is based.
name <- "Fred" age <- 50 anniversary <- as.Date("1991-10-12") glue('My name is {name},', 'my age next year is {age + 1},', 'my anniversary is {format(anniversary, "%A, %B %d, %Y")}.') # single braces can be inserted by doubling them glue("My name is {name}, not {{name}}.") # Named arguments can be used to assign temporary variables. glue('My name is {name},', ' my age next year is {age + 1},', ' my anniversary is {format(anniversary, "%A, %B %d, %Y")}.', name = "Joe", age = 40, anniversary = as.Date("2001-10-12")) # `glue()` can also be used in user defined functions intro <- function(name, profession, country){ glue("My name is {name}, a {profession}, from {country}") } intro("Shelmith", "Senior Data Analyst", "Kenya") intro("Cate", "Data Scientist", "Kenya") # `glue_data()` is useful in magrittr pipes if (require(magrittr)) { mtcars %>% glue_data("{rownames(.)} has {hp} hp") # Or within dplyr pipelines if (require(dplyr)) { head(iris) %>% mutate(description = glue("This {Species} has a petal length of {Petal.Length}")) }} # Alternative delimiters can also be used if needed one <- "1" glue("The value of $e^{2\\pi i}$ is $<<one>>$.", .open = "<<", .close = ">>")
name <- "Fred" age <- 50 anniversary <- as.Date("1991-10-12") glue('My name is {name},', 'my age next year is {age + 1},', 'my anniversary is {format(anniversary, "%A, %B %d, %Y")}.') # single braces can be inserted by doubling them glue("My name is {name}, not {{name}}.") # Named arguments can be used to assign temporary variables. glue('My name is {name},', ' my age next year is {age + 1},', ' my anniversary is {format(anniversary, "%A, %B %d, %Y")}.', name = "Joe", age = 40, anniversary = as.Date("2001-10-12")) # `glue()` can also be used in user defined functions intro <- function(name, profession, country){ glue("My name is {name}, a {profession}, from {country}") } intro("Shelmith", "Senior Data Analyst", "Kenya") intro("Cate", "Data Scientist", "Kenya") # `glue_data()` is useful in magrittr pipes if (require(magrittr)) { mtcars %>% glue_data("{rownames(.)} has {hp} hp") # Or within dplyr pipelines if (require(dplyr)) { head(iris) %>% mutate(description = glue("This {Species} has a petal length of {Petal.Length}")) }} # Alternative delimiters can also be used if needed one <- "1" glue("The value of $e^{2\\pi i}$ is $<<one>>$.", .open = "<<", .close = ">>")
The crayon package defines a number of functions used to
color terminal output. glue_col()
and glue_data_col()
functions provide
additional syntax to make using these functions in glue strings easier.
Using the following syntax will apply the function crayon::blue()
to the text 'foo bar'.
{blue foo bar}
If you want an expression to be evaluated, simply place that in a normal brace expression (these can be nested).
{blue 1 + 1 = {1 + 1}}
If the text you want to color contains, e.g., an unpaired quote or a comment
character, specify .literal = TRUE
.
glue_col(..., .envir = parent.frame(), .na = "NA", .literal = FALSE) glue_data_col(.x, ..., .envir = parent.frame(), .na = "NA", .literal = FALSE)
glue_col(..., .envir = parent.frame(), .na = "NA", .literal = FALSE) glue_data_col(.x, ..., .envir = parent.frame(), .na = "NA", .literal = FALSE)
... |
[ For |
.envir |
[ |
.na |
[ |
.literal |
[ |
.x |
[ |
A glue object, as created by as_glue()
.
library(crayon) glue_col("{blue foo bar}") glue_col("{blue 1 + 1 = {1 + 1}}") glue_col("{blue 2 + 2 = {green {2 + 2}}}") white_on_black <- bgBlack $ white glue_col("{white_on_black Roses are {red {colors()[[552]]}}, Violets are {blue {colors()[[26]]}}, `glue_col()` can show \\ {red c}{yellow o}{green l}{cyan o}{blue r}{magenta s} and {bold bold} and {underline underline} too! }") # this would error due to an unterminated quote, if we did not specify # `.literal = TRUE` glue_col("{yellow It's} happening!", .literal = TRUE) # `.literal = TRUE` also prevents an error here due to the `#` comment glue_col( "A URL: {magenta https://github.com/tidyverse/glue#readme}", .literal = TRUE ) # `.literal = TRUE` does NOT prevent evaluation x <- "world" y <- "day" glue_col("hello {x}! {green it's a new {y}!}", .literal = TRUE)
library(crayon) glue_col("{blue foo bar}") glue_col("{blue 1 + 1 = {1 + 1}}") glue_col("{blue 2 + 2 = {green {2 + 2}}}") white_on_black <- bgBlack $ white glue_col("{white_on_black Roses are {red {colors()[[552]]}}, Violets are {blue {colors()[[26]]}}, `glue_col()` can show \\ {red c}{yellow o}{green l}{cyan o}{blue r}{magenta s} and {bold bold} and {underline underline} too! }") # this would error due to an unterminated quote, if we did not specify # `.literal = TRUE` glue_col("{yellow It's} happening!", .literal = TRUE) # `.literal = TRUE` also prevents an error here due to the `#` comment glue_col( "A URL: {magenta https://github.com/tidyverse/glue#readme}", .literal = TRUE ) # `.literal = TRUE` does NOT prevent evaluation x <- "world" y <- "day" glue_col("hello {x}! {green it's a new {y}!}", .literal = TRUE)
glue_collapse()
collapses a character vector of any length into a length 1 vector.
glue_sql_collapse()
does the same but returns a [DBI::SQL()]
object rather than a glue object.
glue_collapse(x, sep = "", width = Inf, last = "") glue_sql_collapse(x, sep = "", width = Inf, last = "")
glue_collapse(x, sep = "", width = Inf, last = "") glue_sql_collapse(x, sep = "", width = Inf, last = "")
x |
The character vector to collapse. |
sep |
a character string to separate the terms. Not
|
width |
The maximum string width before truncating with |
last |
String used to separate the last two items if |
Always returns a length-1 glue object, as created by as_glue()
.
glue_collapse(glue("{1:10}")) # Wide values can be truncated glue_collapse(glue("{1:10}"), width = 5) glue_collapse(1:4, ", ", last = " and ")
glue_collapse(glue("{1:10}")) # Wide values can be truncated glue_collapse(glue("{1:10}"), width = 5) glue_collapse(1:4, ", ", last = " and ")
glue_safe()
and glue_data_safe()
differ from glue()
and glue_data()
in that the safe versions only look up symbols from an environment using
get()
. They do not execute any R code. This makes them suitable for use
with untrusted input, such as inputs in a Shiny application, where using the
normal functions would allow an attacker to execute arbitrary code.
glue_safe(..., .envir = parent.frame()) glue_data_safe(.x, ..., .envir = parent.frame())
glue_safe(..., .envir = parent.frame()) glue_data_safe(.x, ..., .envir = parent.frame())
... |
[ For |
.envir |
[ |
.x |
[ |
A glue object, as created by as_glue()
.
"1 + 1" <- 5 # glue actually executes the code glue("{1 + 1}") # glue_safe just looks up the value glue_safe("{1 + 1}") rm("1 + 1")
"1 + 1" <- 5 # glue actually executes the code glue("{1 + 1}") # glue_safe just looks up the value glue_safe("{1 + 1}") rm("1 + 1")
SQL databases often have custom quotation syntax for identifiers and strings
which make writing SQL queries error prone and cumbersome to do. glue_sql()
and
glue_data_sql()
are analogs to glue()
and glue_data()
which handle the
SQL quoting. glue_sql_collapse()
can be used to collapse DBI::SQL()
objects.
They automatically quote character results, quote identifiers if the glue
expression is surrounded by backticks '`
' and do not quote
non-characters such as numbers. If numeric data is stored in a character
column (which should be quoted) pass the data to glue_sql()
as a
character.
Returning the result with DBI::SQL()
will suppress quoting if desired for
a given value.
Note parameterized queries are generally the safest and most efficient way to pass user defined values in a query, however not every database driver supports them.
If you place a *
at the end of a glue expression the values will be
collapsed with commas, or if there are no values, produce NULL
.
This is useful for (e.g.) the
SQL IN Operator.
glue_sql( ..., .con, .sep = "", .envir = parent.frame(), .open = "{", .close = "}", .na = DBI::SQL("NULL"), .null = character(), .comment = "#", .literal = FALSE, .trim = TRUE ) glue_data_sql( .x, ..., .con, .sep = "", .envir = parent.frame(), .open = "{", .close = "}", .na = DBI::SQL("NULL"), .null = character(), .comment = "#", .literal = FALSE, .trim = TRUE )
glue_sql( ..., .con, .sep = "", .envir = parent.frame(), .open = "{", .close = "}", .na = DBI::SQL("NULL"), .null = character(), .comment = "#", .literal = FALSE, .trim = TRUE ) glue_data_sql( .x, ..., .con, .sep = "", .envir = parent.frame(), .open = "{", .close = "}", .na = DBI::SQL("NULL"), .null = character(), .comment = "#", .literal = FALSE, .trim = TRUE )
... |
[ For |
.con |
[ |
.sep |
[ |
.envir |
[ |
.open |
[ |
.close |
[ |
.na |
[ |
.null |
[ |
.comment |
[ |
.literal |
[ |
.trim |
[ |
.x |
[ |
A DBI::SQL()
object with the given query.
glue_sql_collapse()
to collapse DBI::SQL()
objects.
con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:") iris2 <- iris colnames(iris2) <- gsub("[.]", "_", tolower(colnames(iris))) DBI::dbWriteTable(con, "iris", iris2) var <- "sepal_width" tbl <- "iris" num <- 2 val <- "setosa" glue_sql(" SELECT {`var`} FROM {`tbl`} WHERE {`tbl`}.sepal_length > {num} AND {`tbl`}.species = {val} ", .con = con) # If sepal_length is store on the database as a character explicitly convert # the data to character to quote appropriately. glue_sql(" SELECT {`var`} FROM {`tbl`} WHERE {`tbl`}.sepal_length > {as.character(num)} AND {`tbl`}.species = {val} ", .con = con) # `glue_sql()` can be used in conjuction with parameterized queries using # `DBI::dbBind()` to provide protection for SQL Injection attacks sql <- glue_sql(" SELECT {`var`} FROM {`tbl`} WHERE {`tbl`}.sepal_length > ? ", .con = con) query <- DBI::dbSendQuery(con, sql) DBI::dbBind(query, list(num)) DBI::dbFetch(query, n = 4) DBI::dbClearResult(query) # `glue_sql()` can be used to build up more complex queries with # interchangeable sub queries. It returns `DBI::SQL()` objects which are # properly protected from quoting. sub_query <- glue_sql(" SELECT * FROM {`tbl`} ", .con = con) glue_sql(" SELECT s.{`var`} FROM ({sub_query}) AS s ", .con = con) # If you want to input multiple values for use in SQL IN statements put `*` # at the end of the value and the values will be collapsed and quoted appropriately. glue_sql("SELECT * FROM {`tbl`} WHERE sepal_length IN ({vals*})", vals = 1, .con = con) glue_sql("SELECT * FROM {`tbl`} WHERE sepal_length IN ({vals*})", vals = 1:5, .con = con) glue_sql("SELECT * FROM {`tbl`} WHERE species IN ({vals*})", vals = "setosa", .con = con) glue_sql("SELECT * FROM {`tbl`} WHERE species IN ({vals*})", vals = c("setosa", "versicolor"), .con = con) # If you need to reference variables from multiple tables use `DBI::Id()`. # Here we create a new table of nicknames, join the two tables together and # select columns from both tables. Using `DBI::Id()` and the special # `glue_sql()` syntax ensures all the table and column identifiers are quoted # appropriately. iris_db <- "iris" nicknames_db <- "nicknames" nicknames <- data.frame( species = c("setosa", "versicolor", "virginica"), nickname = c("Beachhead Iris", "Harlequin Blueflag", "Virginia Iris"), stringsAsFactors = FALSE ) DBI::dbWriteTable(con, nicknames_db, nicknames) cols <- list( DBI::Id(iris_db, "sepal_length"), DBI::Id(iris_db, "sepal_width"), DBI::Id(nicknames_db, "nickname") ) iris_species <- DBI::Id(iris_db, "species") nicknames_species <- DBI::Id(nicknames_db, "species") query <- glue_sql(" SELECT {`cols`*} FROM {`iris_db`} JOIN {`nicknames_db`} ON {`iris_species`}={`nicknames_species`}", .con = con ) query DBI::dbGetQuery(con, query, n = 5) DBI::dbDisconnect(con)
con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:") iris2 <- iris colnames(iris2) <- gsub("[.]", "_", tolower(colnames(iris))) DBI::dbWriteTable(con, "iris", iris2) var <- "sepal_width" tbl <- "iris" num <- 2 val <- "setosa" glue_sql(" SELECT {`var`} FROM {`tbl`} WHERE {`tbl`}.sepal_length > {num} AND {`tbl`}.species = {val} ", .con = con) # If sepal_length is store on the database as a character explicitly convert # the data to character to quote appropriately. glue_sql(" SELECT {`var`} FROM {`tbl`} WHERE {`tbl`}.sepal_length > {as.character(num)} AND {`tbl`}.species = {val} ", .con = con) # `glue_sql()` can be used in conjuction with parameterized queries using # `DBI::dbBind()` to provide protection for SQL Injection attacks sql <- glue_sql(" SELECT {`var`} FROM {`tbl`} WHERE {`tbl`}.sepal_length > ? ", .con = con) query <- DBI::dbSendQuery(con, sql) DBI::dbBind(query, list(num)) DBI::dbFetch(query, n = 4) DBI::dbClearResult(query) # `glue_sql()` can be used to build up more complex queries with # interchangeable sub queries. It returns `DBI::SQL()` objects which are # properly protected from quoting. sub_query <- glue_sql(" SELECT * FROM {`tbl`} ", .con = con) glue_sql(" SELECT s.{`var`} FROM ({sub_query}) AS s ", .con = con) # If you want to input multiple values for use in SQL IN statements put `*` # at the end of the value and the values will be collapsed and quoted appropriately. glue_sql("SELECT * FROM {`tbl`} WHERE sepal_length IN ({vals*})", vals = 1, .con = con) glue_sql("SELECT * FROM {`tbl`} WHERE sepal_length IN ({vals*})", vals = 1:5, .con = con) glue_sql("SELECT * FROM {`tbl`} WHERE species IN ({vals*})", vals = "setosa", .con = con) glue_sql("SELECT * FROM {`tbl`} WHERE species IN ({vals*})", vals = c("setosa", "versicolor"), .con = con) # If you need to reference variables from multiple tables use `DBI::Id()`. # Here we create a new table of nicknames, join the two tables together and # select columns from both tables. Using `DBI::Id()` and the special # `glue_sql()` syntax ensures all the table and column identifiers are quoted # appropriately. iris_db <- "iris" nicknames_db <- "nicknames" nicknames <- data.frame( species = c("setosa", "versicolor", "virginica"), nickname = c("Beachhead Iris", "Harlequin Blueflag", "Virginia Iris"), stringsAsFactors = FALSE ) DBI::dbWriteTable(con, nicknames_db, nicknames) cols <- list( DBI::Id(iris_db, "sepal_length"), DBI::Id(iris_db, "sepal_width"), DBI::Id(nicknames_db, "nickname") ) iris_species <- DBI::Id(iris_db, "species") nicknames_species <- DBI::Id(nicknames_db, "species") query <- glue_sql(" SELECT {`cols`*} FROM {`iris_db`} JOIN {`nicknames_db`} ON {`iris_species`}={`nicknames_species`}", .con = con ) query DBI::dbGetQuery(con, query, n = 5) DBI::dbDisconnect(con)
This is a simple wrapper around eval(parse())
, used as the default
transformer.
identity_transformer(text, envir = parent.frame())
identity_transformer(text, envir = parent.frame())
text |
Text (typically) R code to parse and evaluate. |
envir |
environment to evaluate the code in |
vignette("transformers", "glue")
for documentation on creating
custom glue transformers and some common use cases.
These functions make it easy to quote each individual element and are useful
in conjunction with glue_collapse()
. These are thin wrappers around
base::encodeString()
.
single_quote(x) double_quote(x) backtick(x)
single_quote(x) double_quote(x) backtick(x)
x |
A character to quote. |
A character vector of the same length as x
, with the same
attributes (including names and dimensions) but with no class set.
Marked UTF-8 encodings are preserved.
x <- 1:5 glue('Values of x: {glue_collapse(backtick(x), sep = ", ", last = " and ")}')
x <- 1:5 glue('Values of x: {glue_collapse(backtick(x), sep = ", ", last = " and ")}')
This trims a character vector according to the trimming rules used by glue. These follow similar rules to Python Docstrings, with the following features.
Leading and trailing whitespace from the first and last lines is removed.
A uniform amount of indentation is stripped from the second line on, equal to the minimum indentation of all non-blank lines after the first.
Lines can be continued across newlines by using \\
.
trim(x)
trim(x)
x |
A character vector to trim. |
A character vector.
glue(" A formatted string Can have multiple lines with additional indentation preserved ") glue(" \ntrailing or leading newlines can be added explicitly\n ") glue(" A formatted string \\ can also be on a \\ single line ")
glue(" A formatted string Can have multiple lines with additional indentation preserved ") glue(" \ntrailing or leading newlines can be added explicitly\n ") glue(" A formatted string \\ can also be on a \\ single line ")