Last active
August 29, 2015 14:16
-
-
Save fliptopbox/9a69216efbe157ee62ab to your computer and use it in GitHub Desktop.
javascript: wordwrap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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