1var baseToString = require('./_baseToString'), 2 castSlice = require('./_castSlice'), 3 hasUnicode = require('./_hasUnicode'), 4 isObject = require('./isObject'), 5 isRegExp = require('./isRegExp'), 6 stringSize = require('./_stringSize'), 7 stringToArray = require('./_stringToArray'), 8 toInteger = require('./toInteger'), 9 toString = require('./toString'); 10 11/** Used as default options for `_.truncate`. */ 12var DEFAULT_TRUNC_LENGTH = 30, 13 DEFAULT_TRUNC_OMISSION = '...'; 14 15/** Used to match `RegExp` flags from their coerced string values. */ 16var reFlags = /\w*$/; 17 18/** 19 * Truncates `string` if it's longer than the given maximum string length. 20 * The last characters of the truncated string are replaced with the omission 21 * string which defaults to "...". 22 * 23 * @static 24 * @memberOf _ 25 * @since 4.0.0 26 * @category String 27 * @param {string} [string=''] The string to truncate. 28 * @param {Object} [options={}] The options object. 29 * @param {number} [options.length=30] The maximum string length. 30 * @param {string} [options.omission='...'] The string to indicate text is omitted. 31 * @param {RegExp|string} [options.separator] The separator pattern to truncate to. 32 * @returns {string} Returns the truncated string. 33 * @example 34 * 35 * _.truncate('hi-diddly-ho there, neighborino'); 36 * // => 'hi-diddly-ho there, neighbo...' 37 * 38 * _.truncate('hi-diddly-ho there, neighborino', { 39 * 'length': 24, 40 * 'separator': ' ' 41 * }); 42 * // => 'hi-diddly-ho there,...' 43 * 44 * _.truncate('hi-diddly-ho there, neighborino', { 45 * 'length': 24, 46 * 'separator': /,? +/ 47 * }); 48 * // => 'hi-diddly-ho there...' 49 * 50 * _.truncate('hi-diddly-ho there, neighborino', { 51 * 'omission': ' [...]' 52 * }); 53 * // => 'hi-diddly-ho there, neig [...]' 54 */ 55function truncate(string, options) { 56 var length = DEFAULT_TRUNC_LENGTH, 57 omission = DEFAULT_TRUNC_OMISSION; 58 59 if (isObject(options)) { 60 var separator = 'separator' in options ? options.separator : separator; 61 length = 'length' in options ? toInteger(options.length) : length; 62 omission = 'omission' in options ? baseToString(options.omission) : omission; 63 } 64 string = toString(string); 65 66 var strLength = string.length; 67 if (hasUnicode(string)) { 68 var strSymbols = stringToArray(string); 69 strLength = strSymbols.length; 70 } 71 if (length >= strLength) { 72 return string; 73 } 74 var end = length - stringSize(omission); 75 if (end < 1) { 76 return omission; 77 } 78 var result = strSymbols 79 ? castSlice(strSymbols, 0, end).join('') 80 : string.slice(0, end); 81 82 if (separator === undefined) { 83 return result + omission; 84 } 85 if (strSymbols) { 86 end += (result.length - end); 87 } 88 if (isRegExp(separator)) { 89 if (string.slice(end).search(separator)) { 90 var match, 91 substring = result; 92 93 if (!separator.global) { 94 separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g'); 95 } 96 separator.lastIndex = 0; 97 while ((match = separator.exec(substring))) { 98 var newEnd = match.index; 99 } 100 result = result.slice(0, newEnd === undefined ? end : newEnd); 101 } 102 } else if (string.indexOf(baseToString(separator), end) != end) { 103 var index = result.lastIndexOf(separator); 104 if (index > -1) { 105 result = result.slice(0, index); 106 } 107 } 108 return result + omission; 109} 110 111module.exports = truncate; 112