漂亮的字符串打印(确保自动换行符保持在给定的打印范围内)

时间:2012-08-28 13:54:10

标签: string r pretty-print

我尝试坚持80个字符的打印边距,用于与字符串相关的所有内容,特别是关于自定义消息(警告,错误等)。

现在,我总是想知道是否有一种简单的方法可以确保自动确保/强制执行某些打印边际限制,例如:如果超过所选的打印边距,给定的原子串会自动分解为字符串向量。我用谷歌搜索了一下,但没有找到任何符合我需要的东西。

问题

有人想出一个漂亮的“漂亮印刷”功能,但我可以进一步构建吗?


这是我到目前为止所得到的:

功能def

makePretty <- function(
    string,
    print.margin=80,
    ...
){
    out <- string
    if (nchar(string) > print.margin) {
        times       <- ceiling(nchar(string)/print.margin)
        breaks      <- rep(print.margin+1, times)
        breaks      <- cumsum(breaks)
        string.spl  <- unlist(strsplit(string, split=" "))
        seps        <- str_locate_all(string, " ")[[1]][,"start"]
        queue       <- NA

        envir <- environment()
        out <- unlist(sapply(1:length(breaks), function(ii) {
            idx.next    <- breaks[ii]
            if (ii < length(breaks)) {
                idx <- which(seps <= idx.next)
                chunk <- string.spl[idx]
                envir$string.spl   <- envir$string.spl[-idx]
                envir$seps      <- envir$seps[-idx]       
            } else {
                chunk <- string.spl
            }
            chunk <- paste(chunk, collapse=" ")
            # Chunk could exceed print margin in case the right hand neighbor
            # wasn't a blank >> check again 
            if (nchar(chunk) > print.margin) {
                chunk <- makePretty(string=chunk, print.margin=print.margin)
                envir$queue <- chunk[length(chunk)]
                chunk <- chunk[-length(chunk)]
            } else {
                if (!is.na(envir$queue)) {
                    # Prepend chunk with queued chunk
                    chunk <- paste(envir$queue, chunk, sep=" ")
                    # Reset queue
                    envir$queue <- NA
                }
            }
            # /
            out <- chunk
            return(out)
        })) 
    }
    return(out)
}

功能应用

string <- "This is just an example of a very long character string that exceeds the default print margin of 80 and therefore needs some pretty printing. In fact it's so long that it needs to be broken down into three parts."
> makePretty(string=string)
[1] "This is just an example of a very long character string that exceeds the default"
[2] "print margin of 80 and therefore needs some pretty printing. In fact it's so"    
[3] "long that it needs to be broken down into three parts."      

> string <- "This is just an example of a very long character string that exceeds a certain print margin and therefore needs some pretty printing. In fact it's so long that it needs to be broken down into numerous parts."
> makePretty(string=string, print.margin=40)
[1] "This is just an example of a very long"       
[2] "character string that exceeds a certain"      
[3] "print margin and therefore needs some"        
[4] "pretty printing. In fact it's so long"        
[5] "that it needs to be broken down into numerous"
[6] "parts."    

string <- "This is just an example of a very long character string that exceeds the default print margin of 80 and therefore needs some pretty printing. In fact it's so looooooooooooooooooooooooooooooooong that it needs to be broken down into four parts."
> makePretty(string=string)
[1] "This is just an example of a very long character string that exceeds the default"
[2] "print margin of 80 and therefore needs some pretty printing. In fact it's so"    
[3] "looooooooooooooooooooooooooooooooong that it needs to be broken down into four"  
[4] "parts." 

string <- "This is just an example of a very long character string that exceeds the default print margin of 80 and therefore needs some pretty printing. In fact it's soooooooo looooooooooooooooooooooooooooooooong that it needs to be broken down into four parts."
> makePretty(string=string)
[1] "This is just an example of a very long character string that exceeds the default"
[2] "print margin of 80 and therefore needs some pretty printing. In fact it's"       
[3] "soooooooo looooooooooooooooooooooooooooooooong that it needs to be broken down"  
[4] "into four parts."

到目前为止,该方法仅依靠空白来确定哪些词属于一起 - 这可能不会涵盖其他“真实场景”,如冒号,冒号等。

1 个答案:

答案 0 :(得分:16)

基本R函数strwrap似乎完全符合您的描述:

strwrap(x, width=80)
[1] "This is just an example of a very long character string that exceeds the"    
[2] "default print margin of 80 and therefore needs some pretty printing. In fact"
[3] "it's so long that it needs to be broken down into three parts."              

strwrap(x, 40)
[1] "This is just an example of a very long" "character string that exceeds the"     
[3] "default print margin of 80 and"         "therefore needs some pretty printing." 
[5] "In fact it's so long that it needs to"  "be broken down into three parts."

您可以将paste与参数collapse="\n"结合使用,将这些部分组合成一个带换行符的字符串:

cat(paste(strwrap(x, 40), collapse="\n"))
This is just an example of a very long
character string that exceeds the
default print margin of 80 and
therefore needs some pretty printing.
In fact it's so long that it needs to
be broken down into three parts.