0

Problem

  1. Turn assignment equal signs into assignment arrows.
  2. Use base R only (no styler or formatR).

Context

https://github.com/ropensci/drake/issues/562

Example

Input:

f = function(x = 1){}

Desired output:

f <- function(x = 1){}
landau
  • 5,636
  • 1
  • 22
  • 50
  • Maybe `sub("=", "<-", input)`? Unlike `gsub`, `sub` only replaces the first occurence of the search regex. Note that I don't understand the input you have, is it a character vector? – Rui Barradas Oct 28 '18 at 19:44
  • The input could either be a character vector or language object, either is fine. `sub()` replaces `x = 1` with `x <- 1` in the function's argument list, so unfortunately we cannot use it here. Note the remaining `=` in the desired output. – landau Oct 28 '18 at 19:51
  • If your input is a character vector, then `sub("=", "<-", "f = function(x = 1){}")` outputs what is in the question, `[1] "f <- function(x = 1){}"`. I am clearly missing something. Sorry for the noise. – Rui Barradas Oct 28 '18 at 19:56

1 Answers1

2

Posted in-issue but might as well try for some SO pts:

library(magrittr)

raw_src <- "z = {f('#') # comment

x <- 5
y = 'test'
    }"

# so we can have some tasty parse data
first <- parse(text = raw_src, keep.source = TRUE)

# this makes a nice data frame of the tokenized R source including line and column positions of the source bits
src_info <- getParseData(first, TRUE)

# only care about those blasphemous = assignments
elements_with_equals_assignment <- subset(src_info, token == "EQ_ASSIGN")

# take the source and split it into lines
raw_src_lines <- strsplit(raw_src, "\n")[[1]]

# for as many instances in the data frame replace the = with <-
for (idx in 1:nrow(elements_with_equals_assignment)) {
  stringi::stri_sub(
    raw_src_lines[elements_with_equals_assignment[idx, "line1"]],
    elements_with_equals_assignment[idx, "col1"],
    elements_with_equals_assignment[idx, "col2"]
  ) <- "<-"
}

# put the lines back together and do the thing
parse(
  text = paste0(raw_src_lines, collapse="\n"),
  keep.source = FALSE
)[[1]] %>%
  deparse() %>%
  cat(sep = "\n")
## z <- {
##     f("#")
##     x <- 5
##     y <- "test"
## }
hrbrmstr
  • 77,368
  • 11
  • 139
  • 205