How do you justify text in R? By justify I mean that each line in a paragraph is exactly the same length (like when you justify in open office or excel). I have tried to f
@jenesaisquoi - great solution! But I found it does not work if there is a paragraph break with a space or if strs <- strwrap(string, width=width)
returns one or fewer elements.
So, I found an improved version that first splits string by paragraph/line breaks and then applies the same logic:
justify = function(string, width = getOption('width'),
fill = c('random', 'right', 'left')) {
# Split text into paragraphs and remove trailing and leading white space.
paragraphs = gsub("^\\s+|\\s+$", "",
unlist(strsplit(x = string, split = "\n", fixed = TRUE)))
# NOTE: Empty elements are paragraphs break.
paragraphs = paragraphs[nchar(paragraphs) > 0]
formatted_text = lapply(paragraphs, function(paragraph){
strs = strwrap(paragraph, width = width)
paste(fill_spaces(strs, width, fill), collapse = "\n")
})
paste0(unlist(formatted_text, recursive = FALSE), collapse = "\n")
}
fill_spaces = function(lines, width, fill) {
tokens = strsplit(lines, '\\s+')
res = lapply(head(tokens, -1L), function(x) {
nspace = length(x) - 1L
extra = width - sum(nchar(x)) - nspace
reps = extra %/% nspace
extra = extra %% nspace
times = rep.int(if (reps > 0) reps + 1L else 1L, nspace)
if (extra > 0) {
if (fill == 'right') times[1:extra] = times[1:extra] + 1L
else if (fill == 'left')
times[(nspace - extra + 1L):nspace] = times[(nspace - extra + 1L):nspace] + 1L
else times[inds] = times[(inds <- sample(nspace, extra))] + 1L
}
spaces <- c('', unlist(lapply(times, formatC, x = ' ', digits = NULL)))
paste(c(rbind(spaces, x)), collapse = '')
})
c(res, paste(tail(tokens, 1L)[[1]], collapse = ' '))
}
nchar_per_line = 50
string = "Colin\'s practice outfits have reached a new level recently. It's difficult to determine the effect they are having on his teammates - whether they serve more as a distraction or a nice bit of comice releif, but it is clear they fuel Colin's fire and act as a motivator to him. \n\n On another note, Colin's high fives per 36 have been through the roof recently. It really seems like something he's been focusing on in practice lately, as well as putting extra reps in at the gym. \n\n Keep an eye out for Colin, could be an interesting 10 day pickup down the line."
cat(justify(string, width = nchar_per_line))
# Colin's practice outfits have reached a new level
# recently. It's difficult to determine the effect
# they are having on his teammates - whether they
# serve more as a distraction or a nice bit of
# comice releif, but it is clear they fuel Colin's
# fire and act as a motivator to him.
# On another note, Colin's high fives per 36 have
# been through the roof recently. It really seems
# like something he's been focusing on in practice
# lately, as well as putting extra reps in at the
# gym.
# Keep an eye out for Colin, could be an
# interesting 10 day pickup down the line.