I try to stick to a print margin of 80 characters for everything related to character strings, especially concerning custom-made messages (warnings, errors etc.)
Now, I always wondered if there's an easy way to make sure that some print margin restrictions are automatically ensured/enforced, e.g. that a given atomic string is automatically broken down into a vector of character strings in case it exceeds the chosen print margin. I've googled a bit but didn't really find anything that fits my needs.
Did someone come up with a nice "pretty-printing" function yet that I could further build upon?.
This is what I came up with myself so far:
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."
So far, the approach solely relies on blank spaces to determine which words belong together - which is probably not covering other "real world scenarios" such as colons, semi-colons etc.
The base R function strwrap
seems to do exactly what you describe:
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."
And you can use paste
with the argument collapse="\n"
to combine the pieces into a single string with newlines:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With