My goal is:
I'm able to limit the number of characters per line correctly, but I'm having trouble with the white space, etc...
Any help would be appreciated
var str = `i am a string that has new lines and whitespace. I need to preserve the leading whitespace and add it back on after the string has been broken up after n characters.
This line has leading whitespace. Tttttt rrrrrr
ttgvgggjjj. Gyjfry bh jkkfrtuj hhdt iihdrtttg.
Here is another line. Hjkkl gggdetu jcfgjbfftt.
This line has no leading whitespace, so i dont need any reapplied. Jjjxsrg bjlkdetyhk llhfftt`;
function addNewlines(str) {
var result = '';
while(str.length > 0) {
result += str.substring(0, 25) + '<br />';
str = str.substring(25);
}
return result;
}
var newStr = addNewlines(str).toString();
document.getElementById("result").innerHTML = newStr;
Should end up looking something like this:
i am a string that has ne
w lines and whitespace. I
need to preserve the lea
ding whitespace and add i
t back on after the strin
g has been broken up afte
r n characters.
This line has leading
whitespace. Tttttt rr
rrrr ttgvgggjjj. Gyjf
ry bh jkkfrtuj hhdt i
ihdrtttg. Here is ano
ther line. Hjkkl gggd
etu jcfgjbfftt.
This line has no leading
whitespace, so i dont n
eed any reapplied. Jjjx
srg bjlkdetyhk llhfftt
Sometimes when dealing with a new algorithm, is much easier to use two or more passes. So you think how it would work in steps instead of everything at once.
I have an implementation working that have 2 passes: first I join the paragraph lines, and in the second pass I perform the actual splitting.
I'm sure there's a better approach, but this works and is fully commented.
I wasn't sure your version of ES so I made it ES5-compatible.
https://jsfiddle.net/2ngtj3aj/
// Divides a string into chunks of specific size
function chunk(str, size) {
var chunks = [];
while(str) {
chunks.push(str.substring(0, size));
str = str.substring(size);
}
return chunks;
}
// Removes all spaces from the left of a string
function trimLeft(str) {
while(str.substr(0,1) == " ") {
str = str.substr(1);
}
return str;
}
// Repeats a character n times
function repeat(c, n) {
return Array(n + 1).join(c);
}
function addNewlines(str) {
var MAX_COLS = 25; // maximum colums on the text
var DEFAULT_LEADING = 3; // default leading to reapply
var MIN_LEADING = 1; // minimum amount of spacing to be considered a paragraph
var CR = "\n";
var result = '';
var leading = 0;
var chunks = [];
var formattedLines = []; // store the intermediary lines
var startLeadingSpaceLine = -1; // where does a paragrph start
var i, l; // counters
var lines = str.split(CR); // input lines
// In the first pass, we join the paragraph lines
for (i = 0; i < lines.length; i++) {
l = lines[i];
// If line is empty, we don't use it
if (l.trim() == "") continue;
if (l.substr(0, MIN_LEADING) == repeat(" ", MIN_LEADING)) {
// If line has leading whitespace, remove the leading space
l = trimLeft(l);
if (startLeadingSpaceLine > -1) {
// If we are already on a paragraph,
// we don't overwrite the flag
} else {
// But if this is the first line of an paragraph,
// We set a flag to allow to join this line with the next one
// if that contains identation as well
startLeadingSpaceLine = i;
}
// If we are on a paragraph, we don't add this line to the array,
// first we need to wait to see if we have more lines in the paragraph
// We also update the line in the array with the whitespace removed
lines[i] = l;
continue;
} else {
// If line doesn't has whitespace, we check if we have just finished
// an paragraph
if (startLeadingSpaceLine > -1) {
// If we do, then we need to add the previous lines to the array
// Note: if we want to leave a space between lines, we need to use
// join(' ') instead of join('')
var paragraphLines = lines.slice(startLeadingSpaceLine, i).join('');
// We add the whitespace we like
paragraphLines = repeat(" ", DEFAULT_LEADING) + paragraphLines;
formattedLines.push(paragraphLines);
}
}
formattedLines.push(l);
}
// Now we parse again the lines, this time we will divide
// the lines into chunks
for (i = 0; i < formattedLines.length; i++) {
l = formattedLines[i];
// Now check against DEFAULT_LEADAING since we have already changed
// the identation
if (l.substr(0, DEFAULT_LEADING) == repeat(" ", DEFAULT_LEADING)) {
// If line has leading whitespace, remove the leading space
// We aded it before just to be able to detect the paragraph.
l = trimLeft(l);
// Divide the line into chunks. We take into account the space
// we have removed, otherwise the paragraph will bleed to the
// right.
l = chunk(l, MAX_COLS - DEFAULT_LEADING);
// We add leading space to all paragraph lines
for(var j = 0; j < l.length; j++) {
l[j] = repeat(" ", DEFAULT_LEADING) + l[j];
}
// Optional: we add blank lines between paragraphs
l = [" "].concat(l).concat([" "]);
} else {
// If we have a simple line, just divide it into chunks
l = chunk(l, MAX_COLS);
}
// Join the lines with newlines and add to the result
l = l.join(CR);
result += l + CR;
}
return result;
}
var process = function() {
var newStr = addNewlines(input.value).toString();
document.getElementById("result").innerHTML = newStr;
}
var input = document.getElementById("input");
input.addEventListener("change", process);
input.addEventListener("keyup", process);
process();
<h3>RESULTS</h3>
<textarea id="input" rows="10" cols="80">i am a string that has new lines and whitespace. I need to preserve the leading whitespace and add it back on after the string has been broken up after n characters.
This line has leading whitespace. Tttttt rrrrrr
ttgvgggjjj. Gyjfry bh jkkfrtuj hhdt iihdrtttg.
Here is another line. Hjkkl gggdetu jcfgjbfftt.
This line has no leading whitespace, so i dont need any reapplied. Jjjxsrg bjlkdetyhk llhfftt</textarea>
<pre id="result"></pre>