Skip to content

Instantly share code, notes, and snippets.

@fliptopbox
Last active August 29, 2015 14:16
Show Gist options
  • Save fliptopbox/9a69216efbe157ee62ab to your computer and use it in GitHub Desktop.
Save fliptopbox/9a69216efbe157ee62ab to your computer and use it in GitHub Desktop.
javascript: wordwrap
/*
String.wordwrap(@length INT [ @spill INT ])
A String prototype to wrap long strings into lines with an ideal length
by recurrsively itterating over the string, to complie an array of lines.
Arguments:
@length: INT (required) - ideal string length of characters per line
@spill: INT (optional) - margin of tolerance, a greedy look ahead
e.g. String.wordwrap(5, 2);
// ideal length, 5 charcters, with a tollerance of up-to 7 characters (i.e. 5+2)
Usgae:
var x = 'A very long string that you want to wrap into lines';
x.wordwrap(15); // ["A very long", "string that you", "want to wrap", "into lines"]
var x = 'abcdefghijklmnopqrstuvwxyz, it will truncate extremely long words'
x.wordwrap(12, 3); // ["abcdefghijklmno", "pqrstuvwxyz, it", "will truncate", "extremely long", "words"]
*/
(function () {
var wordArray = [],
wrapArray = [],
idealLength,
spillLength,
nextWord,
nextWordLen,
valueLen,
newLength,
maxWordLength,
overflow,
eof, tmp, diff,
getNextWord,
showTotalLen = 0,
wordLoop = function (value, i) {
/* returns an array of trimmed lines */
i = i || 0;
tmp = diff = null;
value = value || wordArray[i] || '';
valueLen = value.length;
nextWord = (wordArray[i + 1]) || '';
nextWordLen = nextWord.length || 0;
newLength = (valueLen + nextWordLen);
overflow = (newLength >= idealLength) && (newLength >= spillLength);
maxWordLength = Math.max(idealLength, spillLength);
eof = !wordArray[i + 1];
getNextWord = (!eof && !overflow);
candidate = (value + ' ' + nextWord);
if (getNextWord) {
return wordLoop(candidate, i + 1);
}
/*
Exception catcher:
ensure the next word length is shorter than max length
*/
if (nextWordLen >= maxWordLength) {
tmp = (candidate).slice(0, maxWordLength);
diff = (candidate).length - tmp.length;
wordArray[i + 1] = nextWord.slice(-diff);
value = tmp;
}
/*
Exception catcher:
truncate extremely long strings, update word array,
and recurse the remainder
*/
if (value.length > maxWordLength) {
console.log('!@');
tmp = value.slice(0, maxWordLength);
diff = value.length - tmp.length;
wrapArray.push(tmp);
value = value.slice(-diff);
return wordLoop(value, i);
}
if (value) {
wrapArray.push(value.trim());
return wordLoop('', i + 1);
}
return wrapArray;
},
main = function (length, spill) {
wrapArray = []; // clear existing array
wordArray = (this).trim().split(' ');
idealLength = (length && length.constructor === Number && length > 0) ? length : parseInt(this.length / 5, 10);
spill = (spill && spill.constructor === Number && spill > 0) ? spill : 0;
spillLength = (idealLength + spill);
console.log(idealLength, spillLength);
return wordLoop();
};
String.prototype.wordwrap = main;
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment