Created
June 19, 2012 00:41
-
-
Save larzconwell/2951662 to your computer and use it in GitHub Desktop.
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
/* | |
* Truncate(string<String>, options<Object>, callback[Function]) | |
* | |
* Truncates a given `string` after a specified `length` if `string` is longer than | |
* `length`. The last characters will be replaced with an `omission` for a total length not | |
* exceeding `length`. If `callback` is given it will fire if `string` is truncated. | |
* | |
* Options: | |
* length <Integer> Length the output string will be(default: 30) | |
* omission <String> Replace last letters with an omission(default: '...') | |
* ellipsis <String> Alias for omission | |
* seperator <String>/<RegExp> Break the truncated text at the nearest `seperator` | |
* | |
* Warnings: | |
* Please be aware that truncating HTML tags or entities may result in malformed HTML returned | |
* | |
* Examples: | |
* truncate('Once upon a time in a world', { length: 10 }) | |
* => 'Once upo...' | |
* | |
* truncate('Once upon a time in a world', { length: 20, omission: '...(continued)' }) | |
* => 'Once u...(continued)' | |
* | |
* truncate('Once upon a time in a world', { length: 15, seperator: ' ' }) | |
* => 'Once upon a...' | |
* Normal Output: => 'Once upon a ...' | |
*/ | |
exports.truncate = { | |
name: 'truncate', | |
action: function(string, options, callback) { | |
if(!string) return; | |
options = options || {}; | |
// Set `options` defaults | |
options.length = options.length || 30; | |
options.omission = options.omission || options.ellipsis || '...'; | |
if(typeof options.escape === 'undefined') options.escape = true; | |
var stringLen = string.length | |
, stringLenWithOmission = options.length - options.omission.length | |
, last; | |
// Set the index to stop at for `string` | |
if(options.seperator) { | |
if(options.seperator instanceof RegExp) { | |
// If `options.seperator` is a regex search | |
if(options.seperator.global) { | |
options.seperator = options.seperator; | |
} else { | |
var ignoreCase = options.seperator.ignoreCase ? 'i' : '' | |
, multiLine = options.seperator.multiLine ? 'm' : ''; | |
options.seperator = new RegExp(options.seperator.source, 'g' + ignoreCase + multiLine); | |
} | |
var stringToWorkWith = string.substring(0, stringLenWithOmission + 1) | |
, lastIndexOf = -1 | |
, nextStop = 0 | |
, result; | |
while((result = options.seperator.exec(stringToWorkWith)) !== null) { | |
lastIndexOf = result.index; | |
options.seperator.lastIndex = ++nextStop; | |
} | |
last = lastIndexOf; | |
} else { | |
last = string.lastIndexOf(options.seperator, stringLenWithOmission); | |
} | |
// If the above couldn't be found, they'll default to -1 so, we need to just set | |
// - it as `stringLenWithOmission` | |
if(last === -1) last = stringLenWithOmission; | |
} else last = stringLenWithOmission; | |
if(stringLen < options.length) return string; | |
return string.substring(0, last) + options.omission; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment