Skip to content
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
Closed

Allow custom delimiters #23

baptiste opened this issue May 7, 2017 · 2 comments

Comments

@baptiste
Copy link
Contributor

baptiste commented May 7, 2017

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

@egnha
Copy link
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
Copy link
Collaborator

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 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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants