Enhanced tidy.source() (Preserve Some Comments)

March 31, 2009

(This article was first published on Keep on Fighting! » R Language, and kindly contributed to R-bloggers)

After a few hours’ work, I modified the function tidy.source() in the animation package so that it can preserve complete comment lines. See the tidy.source() wiki page for example.

Downdload the R code here

tidy.source <- function(source = "clipboard", keep.comment = TRUE,
  keep.blank.line = FALSE, begin.comment, end.comment, ...) {
  # parse and deparse the code
  tidy.block = function(block.text) {
      exprs = parse(text = block.text)
      n = length(exprs)
      res = character(n)
      for (i in 1:n) {
        dep = paste(deparse(exprs[i]), collapse = "\n")
        res[i] = substring(dep, 12, nchar(dep) - 1)
  text.lines = readLines(source, warn = FALSE)
  if (keep.comment) {
      # identifier for comments
      identifier = function() paste(sample(LETTERS), collapse = "")
      if (missing(begin.comment))
        begin.comment = identifier()
      if (missing(end.comment))
        end.comment = identifier()
      # remove leading and trailing white spaces
      text.lines = gsub("^[[:space:]]+|[[:space:]]+$", "",
      # make sure the identifiers are not in the code
      # or the original code might be modified
      while (length(grep(sprintf("%s|%s", begin.comment, end.comment),
        text.lines))) {
        begin.comment = identifier()
        end.comment = identifier()
      head.comment = substring(text.lines, 1, 1) == "#"
      # add identifiers to comment lines to cheat R parser
      if (any(head.comment)) {
        text.lines[head.comment] = gsub("\"", "\'", text.lines[head.comment])
        text.lines[head.comment] = sprintf("%s=\"%s%s\"",
          begin.comment, text.lines[head.comment], end.comment)
      # keep blank lines?
      blank.line = text.lines == ""
      if (any(blank.line) & keep.blank.line)
        text.lines[blank.line] = sprintf("%s=\"%s\"", begin.comment,
      text.tidy = tidy.block(text.lines)
      # remove the identifiers
      text.tidy = gsub(sprintf("%s = \"|%s\"", begin.comment,
        end.comment), "", text.tidy)
  else {
      text.tidy = tidy.block(text.lines)
  cat(paste(text.tidy, collapse = "\n"), "\n", ...)

Note that inline comments will still be removed. I don’t want to spend more time on dealing with inline comments any more.

Related Posts

To leave a comment for the author, please follow the link and comment on their blog: Keep on Fighting! » R Language.

R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: Data science, Big Data, R jobs, visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...

If you got this far, why not subscribe for updates from the site? Choose your flavor: e-mail, twitter, RSS, or facebook...

Tags: , , , ,

Comments are closed.

Search R-bloggers


Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)