main.js (3031B)
1 /** 2 * @license Apache-2.0 3 * 4 * Copyright (c) 2021 The Stdlib Authors. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 'use strict'; 20 21 // MODULES // 22 23 var isString = require( '@stdlib/assert/is-string' ).isPrimitive; 24 var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive; 25 var numGraphemeClusters = require( './../../num-grapheme-clusters' ); 26 var nextGraphemeClusterBreak = require( './../../next-grapheme-cluster-break' ); 27 var format = require( './../../format' ); 28 29 30 // MAIN // 31 32 /** 33 * Truncates a string to a specified length. 34 * 35 * @param {string} str - input string 36 * @param {integer} len - output string length (including ending) 37 * @param {string} [ending='...'] - custom ending 38 * @throws {TypeError} first argument must be a string 39 * @throws {TypeError} second argument must be a nonnegative integer 40 * @throws {TypeError} third argument must be a string 41 * @returns {string} truncated string 42 * 43 * @example 44 * var str = 'beep boop'; 45 * var out = truncate( str, 7 ); 46 * // returns 'beep...' 47 * 48 * @example 49 * var str = 'beep boop'; 50 * var out = truncate( str, 5, '>>>' ); 51 * // returns 'be>>>' 52 * 53 * @example 54 * var str = 'beep boop'; 55 * var out = truncate( str, 10 ); 56 * // returns 'beep boop' 57 * 58 * @example 59 * var str = 'beep boop'; 60 * var out = truncate( str, 0 ); 61 * // returns '' 62 * 63 * @example 64 * var str = 'beep boop'; 65 * var out = truncate( str, 2 ); 66 * // returns '..' 67 * 68 * @example 69 * var str = '🐺 Wolf Brothers 🐺'; 70 * var out = truncate( str, 6 ); 71 * // returns '🐺 W...' 72 */ 73 function truncate( str, len, ending ) { 74 var endingLength; 75 var fromIndex; 76 var nVisual; 77 var idx; 78 if ( !isString( str ) ) { 79 throw new TypeError( format( 'invalid argument. First argument must be a string. Value: `%s`.', str ) ); 80 } 81 if ( !isNonNegativeInteger( len ) ) { 82 throw new TypeError( format( 'invalid argument. Second argument must be a nonnegative integer. Value: `%s`.', len ) ); 83 } 84 if ( arguments.length > 2 ) { 85 if ( !isString( ending ) ) { 86 throw new TypeError( format( 'invalid argument. Third argument must be a string. Value: `%s`.', ending ) ); 87 } 88 } 89 ending = ending || '...'; 90 endingLength = numGraphemeClusters( ending ); 91 fromIndex = 0; 92 if ( len > numGraphemeClusters( str ) ) { 93 return str; 94 } 95 if ( len - endingLength < 0 ) { 96 return ending.slice( 0, len ); 97 } 98 nVisual = 0; 99 while ( nVisual < len - endingLength ) { 100 idx = nextGraphemeClusterBreak( str, fromIndex ); 101 fromIndex = idx; 102 nVisual += 1; 103 } 104 return str.substring( 0, idx ) + ending; 105 } 106 107 108 // EXPORTS // 109 110 module.exports = truncate;