7). tidy.dir: 对dir目录下,所有R脚本进行格式化
新建目录:dir
新建两个R脚本文件:dir.r, dir2.r
~ mkdir dir~ vi dir.ra<-1+1;a;matrix(rnorm(10),5);~ vi dir2.rif(a>2) { b=c('11',832);"#a>2";} else print('a is invalid!!')执行tidy.dir
> tidy.dir(path="dir")tidying dir/dir.rtidying dir/dir2.r分别查看dir.r和dir2.r
~ vi dir.ra <- 1 + 1amatrix(rnorm(10), 5) ~ vi dir2.rif (a > 2) { b = c("11", 832) "#a>2"} else print("a is invalid!!") 我们发现不规则的代码,已经被格式化了!!
5. formatR的源代码解析通过上面的使用,我们不难发现formatR包的核心函数,就是tidy.source函数,从github上面找到源代码:https://github.com/yihui/formatR/blob/master/R/tidy.R
我将在代码中增加注释:
tidy.source = function( source = 'clipboard', keep.comment = getOption('keep.comment', TRUE), keep.blank.line = getOption('keep.blank.line', TRUE), replace.assign = getOption('replace.assign', FALSE), left.brace.newline = getOption('left.brace.newline', FALSE), reindent.spaces = getOption('reindent.spaces', 4), output = TRUE, text = NULL, width.cutoff = getOption('width'), ...) { ## 判断输入来源为剪贴板 if (is.null(text)) { if (source == 'clipboard' && Sys.info()['sysname'] == 'Darwin') { source = pipe('pbpaste') } } else { ## 判断输入来源为字符串 source = textConnection(text); on.exit(close(source)) } ## 按行读取来源数据 text = readLines(source, warn = FALSE) ## 大小处理 if (length(text) == 0L || all(grepl('^\\s*$', text))) { if (output) cat('\n', ...) return(list(text.tidy = text, text.mask = text)) } ## 空行处理 if (keep.blank.line && R3) { one = paste(text, collapse = '\n') # record how many line breaks before/after n1 = attr(regexpr('^\n*', one), 'match.length') n2 = attr(regexpr('\n*$', one), 'match.length') } ## 注释处理 if (keep.comment) text = mask_comments(text, width.cutoff, keep.blank.line) ## 把输入的R代码,先转成表达式,再转回字符串。用来实现对每个语句的截取。 text.mask = tidy_block(text, width.cutoff, replace.assign && length(grep('=', text))) ## 对注释排版 text.tidy = if (keep.comment) unmask.source(text.mask) else text.mask ## 重新定位缩进 text.tidy = reindent_lines(text.tidy, reindent.spaces) ## 扩号换行 if (left.brace.newline) text.tidy = move_leftbrace(text.tidy) ## 增加首尾空行 if (keep.blank.line && R3) text.tidy = c(rep('', n1), text.tidy, rep('', n2)) ## 在console打印格式化后的结果 if (output) cat(paste(text.tidy, collapse = '\n'), '\n', ...) ## 返回,但不打印结果 invisible(list(text.tidy = text.tidy, text.mask = text.mask))}Bug: 没有对”->”进行处理
在读源代码的过程中,发现有一个小问题,没有对”->”进行处理,已经给作者提bug了。
https://github.com/yihui/formatR/issues/31
bug测试代码:
> c('11',832)->x2> x2[1] "11" "832"> tidy.source(text="c('11',832)->x2")c("11", 832) <- x2 > tidy.eval(text="c('11',832)->x2")c("11", 832) <- x2Error in eval(expr, envir, enclos) : object 'x2' not foundBUG已修复:
作者回复:这个问题已经在R 3.0.2中修正了。
> formatR::tidy.source(text="c('11',832)->x2")x2 <- c("11", 832) > sessionInfo()R version 3.0.2 (2013-09-25)Platform: x86_64-pc-linux-gnu (64-bit)locale: [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8 [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 [7] LC_PAPER=en_US.UTF-8 LC_NAME=C [9] LC_ADDRESS=C LC_TELEPHONE=C [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C attached base packages:[1] stats graphics grDevices utils datasets methods base loaded via a namespace (and not attached):[1] formatR_0.10.3formatR包提供的功能非常实用,特别是读别人写的不规范的代码的时候。建议各IDE厂商能把formatR,作为标准的格式化工具直接嵌入编辑器的工具里面。让我们把读别人的代码,也变成一件快乐的事情吧。 |