New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow custom delimiters #23

Closed
baptiste opened this Issue May 7, 2017 · 2 comments

Comments

Projects
None yet
3 participants
@baptiste
Contributor

baptiste commented May 7, 2017

{ } would make it hard to work with some languages such as TeX.

@egnha

This comment has been minimized.

Contributor

egnha commented May 20, 2017

Here's a simple DIY solution: substitute custom delimiters by glue's delimiters, then apply glue.

  • First, make a delimiter converter (which ”escapes” curly braces):
    redelimiter <- function(l, r) {
      redelim <- list(c("\\{", "{{"), c("\\}", "}}"), c(l, "{"), c(r, "}"))
      function(text)
        Reduce(function(x, .) gsub(.[1], .[2], x), redelim, text)
    }
    For example, to convert <<, >> delimiters to glue's delimiters, apply redelimiter("<<", ">>") to your string:
    redelimiter("<<", ">>")("The value of $e^{2\\pi i}$ is $<<one>>$.")
    #> [1] "The value of $e^{{2\\pi i}}$ is ${one}$."
  • Then extend glue() to handle custom delimiters, by “redelimiting” before calling glue. (One has to be careful to pass the interpolation arguments to glue() unevaluated.)
    glue_with_delim <- function(l, r) {
      redelim <- redelimiter(l, r)
      # derived from glue_data()
      restring <- function(..., env) {
        strings <- eval(substitute(alist(...)))
        is_text <- !glue:::has_names(strings)
        strings[is_text] <- redelim(lapply(strings[is_text], eval, envir = env))
        strings
      }
      # same formals as glue()
      function(..., .sep = "", .envir = parent.frame()) {
        strings <- restring(..., env = parent.frame())
        eval(as.call(c(glue::glue, strings, .sep = .sep, .envir = .envir)))
      }
    }
  • With glue_with_delim(), you can make a version of glue() adapted to custom delimiters:
    gum <- glue_with_delim("<<", ">>")
    
    text1 <- "The value of $e^{2\\pi i}$ is $<<one>>$."
    text2 <- "The value of $e^{2\\pi i}+1$ is $<<two>>$."
    gum(text1, text2, one = Re(exp(pi * 2i)), two = one + 1, .sep = "\n")
    #> The value of $e^{2\pi i}$ is $1$.
    #> The value of $e^{2\pi i}+1$ is $2$.
    (gum(), as defined, won't allow you to insert literal <<, >>. But you can lift this limitation by calling glue_with_delim() with appropriate regular expressions, in place of "<<", ">>".)

@jimhester Do you think custom delimiters are better off as DIY?

A disadvantage of the DIY solution presented here is its inefficiency: aside from the call to redelim(), restring() duplicates computations in glue_data().

@jimhester

This comment has been minimized.

Member

jimhester commented May 22, 2017

I think this is an interesting solution. I think modifying the C code to handle this case is probably a better way to go in the package, but you can definitely use something like this until that is implemented.

@jimhester jimhester closed this in b4a07bb May 22, 2017

jimhester added a commit that referenced this issue May 22, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment