diff --git a/README.md b/README.md index 9399f8f..382ae59 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,31 @@ Smart Truncate [![Build Status](https://travis-ci.org/millerized/smart-truncate.svg?branch=master)](https://travis-ci.org/millerized/smart-truncate) [![Coverage Status](https://coveralls.io/repos/github/millerized/smart-truncate/badge.svg?branch=master)](https://coveralls.io/github/millerized/smart-truncate?branch=master) ========= -A small library that truncates a string. It can insert or append an ellipsis at any desired position of the truncated result. +A small library that truncates a string. It can insert or append an ellipsis (or a custom mark) at any desired position of the truncated result. ## Installation - `npm install smart-truncate` + `npm install --save smart-truncate` ## Syntax ```js -smartTruncate(string, length[, position]) +smartTruncate(string, length[, options]) ``` #### Paramaters >**_string_**
-    A string with a minimum lenght of 4 characters. + A string with a minimum length of 4 characters. >**_length_**
-    The length of the truncated result. + The length of the truncated result. ->**_position_**
-    Optional. The index of the ellipsis (zero based). Default is at the end. +>**_options_**
+>**_options.position_**
+ Optional. The index of the ellipsis (zero based). Default is at the end.
+>**_options.mark_**
+ Optional. The character[s] indicating omission. Default is an ellipsis "…". #### Return value ->A new string truncated with an ellipsis. +>A new string truncated with an ellipsis or custom mark. ## Usage ```js @@ -42,7 +45,7 @@ const truncated = smartTruncate(string, 15); const string = 'To iterate is human, to recurse divine.'; // Insert an ellipsis in the middle of a smart truncated string. -const truncated = smartTruncate(string, 21, 10); +const truncated = smartTruncate(string, 21, {position: 10}); ``` **Output**: `"To iterate…se divine."` @@ -60,7 +63,7 @@ const files = [ 'App Store.app' ]; -const truncated = files.map((filename) => smartTruncate(filename, 21, 10)); +const truncated = files.map((filename) => smartTruncate(filename, 21, {position: 10})); ``` **Output**: diff --git a/dist/smart-truncate.es5.js b/dist/smart-truncate.es5.js index 6cccb3f..ac7f879 100644 --- a/dist/smart-truncate.es5.js +++ b/dist/smart-truncate.es5.js @@ -3,18 +3,27 @@ /** * smartTruncate - Smartly™ truncate a given string. * - * @param {String} string A string with a minimum lenght of 4 chars. - * @param {Number} length The length of the truncated result. - * @param {Number} [position] The index of the ellipsis (zero based). Default is the end. - * @return {String} Return a truncated string w/ ellipsis. + * @param {String} string - A string with a minimum lenght of 4 chars. + * @param {Number} length - The length of the truncated result. + * @param {Object} [options] + * @param {Number} [options.position] - The index of the ellipsis (zero based). + * Default is the end. + * @param {String} [options.mark = '…'] - The character[s] indicating omission. + * @return {String} - Return a truncated string w/ ellipsis. * * Example: smartTruncate('Steve Miller', 8) === 'Steve M…'. * Example: smartTruncate('Steve Miller', 9, 4) === 'Stev…ller'. */ var smartTruncate = function smartTruncate(string, length) { - var position = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : length; + var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, + _ref$mark = _ref.mark, + mark = _ref$mark === undefined ? '\u2026' : _ref$mark, + _ref$position = _ref.position, + position = _ref$position === undefined ? length - 1 : _ref$position; - var ellipsisOffset = 1; + if (typeof mark !== 'string') return string; + + var markOffset = mark.length; var minLength = 4; var str = string; @@ -23,19 +32,19 @@ var smartTruncate = function smartTruncate(string, length) { str = str.trim(); } - var invalid = typeof str !== 'string' || str.length < minLength || typeof length !== 'number' || length <= minLength || length >= str.length - ellipsisOffset; + var invalid = typeof str !== 'string' || str.length < minLength || typeof length !== 'number' || length <= minLength || length >= str.length - markOffset; if (invalid) return string; - if (position >= length - ellipsisOffset) { - var _start = str.substring(0, length - ellipsisOffset); - return _start + '\u2026'; + if (position >= length - markOffset) { + var _start = str.substring(0, length - markOffset); + return '' + _start + mark; } var start = str.substring(0, position); - var end = str.slice(position + ellipsisOffset - length); + var end = str.slice(position + markOffset - length); - return start + '\u2026' + end; + return '' + start + mark + end; }; module.exports = smartTruncate; diff --git a/src/smart-truncate.js b/src/smart-truncate.js index a1b98b8..906b80c 100644 --- a/src/smart-truncate.js +++ b/src/smart-truncate.js @@ -1,16 +1,26 @@ /** * smartTruncate - Smartly™ truncate a given string. * - * @param {String} string A string with a minimum lenght of 4 chars. - * @param {Number} length The length of the truncated result. - * @param {Number} [position] The index of the ellipsis (zero based). Default is the end. - * @return {String} Return a truncated string w/ ellipsis. + * @param {String} string - A string with a minimum lenght of 4 chars. + * @param {Number} length - The length of the truncated result. + * @param {Object} [options] + * @param {Number} [options.position] - The index of the ellipsis (zero based). + * Default is the end. + * @param {String} [options.mark = '…'] - The character[s] indicating omission. + * @return {String} - Return a truncated string w/ ellipsis. * * Example: smartTruncate('Steve Miller', 8) === 'Steve M…'. * Example: smartTruncate('Steve Miller', 9, 4) === 'Stev…ller'. */ -const smartTruncate = (string, length, position = length) => { - const ellipsisOffset = 1; +const smartTruncate = (string, length, + { + mark = '\u2026', // ellipsis = … + position = (length - 1), + } = {} +) => { + if (typeof mark !== 'string') return string; + + const markOffset = mark.length; const minLength = 4; let str = string; @@ -23,19 +33,19 @@ const smartTruncate = (string, length, position = length) => { || str.length < minLength || typeof length !== 'number' || length <= minLength - || length >= (str.length - ellipsisOffset); + || length >= (str.length - markOffset); if (invalid) return string; - if (position >= (length - ellipsisOffset)) { - const start = str.substring(0, length - ellipsisOffset); - return `${start}…`; + if (position >= (length - markOffset)) { + const start = str.substring(0, length - markOffset); + return `${start}${mark}`; } const start = str.substring(0, position); - const end = str.slice((position + ellipsisOffset) - length); + const end = str.slice((position + markOffset) - length); - return `${start}…${end}`; + return `${start}${mark}${end}`; } module.exports = smartTruncate; diff --git a/src/smart-truncate.spec.js b/src/smart-truncate.spec.js index b63a54f..483bab2 100644 --- a/src/smart-truncate.spec.js +++ b/src/smart-truncate.spec.js @@ -3,14 +3,14 @@ const {expect} = require('chai'); const smartTruncate = require('../dist/smart-truncate.es5'); -describe('smartTruncate(string, length[, position])', () => { +describe('smartTruncate()', () => { it('should return a smart truncated string w/ an ellipsis at the 4th index position of the given string', () => { - expect(smartTruncate('Steve Miller', 9, 4)).to.equal('Stev…ller'); + expect(smartTruncate('Steve Miller', 9, {position: 4})).to.equal('Stev…ller'); }); it('should assert that the length of the truncated string is equal to the given length w/ an ellipsis at the 4th index position', () => { const length = 9; - const truncated = smartTruncate('Steve Miller', length, 4); + const truncated = smartTruncate('Steve Miller', length, {position: 4}); expect(truncated.length).to.equal(length); }); @@ -25,11 +25,11 @@ describe('smartTruncate(string, length[, position])', () => { }); it('should return a smart truncated string w/ an ellipsis at the 5th index position of the given string', () => { - expect(smartTruncate('Steve Miller', 9, 5)).to.equal('Steve…ler'); + expect(smartTruncate('Steve Miller', 9, {position: 5})).to.equal('Steve…ler'); }); it('should return a smart truncated string w/ an ellipsis at the 8th index position of the given string', () => { - expect(smartTruncate('Not a good fit', 12, 8)).to.equal('Not a go…fit'); + expect(smartTruncate('Not a good fit', 12, {position: 8})).to.equal('Not a go…fit'); }); it('should return the given string when given a length that is larger than the given string', () => { @@ -41,7 +41,7 @@ describe('smartTruncate(string, length[, position])', () => { }); it('should append an ellipsis to the end of the truncated string when given a position that is larger than the given string and length', () => { - expect(smartTruncate('Steve Miller', 10, 14)).to.equal('Steve Mil…'); + expect(smartTruncate('Steve Miller', 10, {position: 14})).to.equal('Steve Mil…'); }); it('should return the given string when given an undefined length', () => { @@ -56,10 +56,11 @@ describe('smartTruncate(string, length[, position])', () => { expect(smartTruncate('Ste ', 2)).to.equal('Ste '); }); - it('should return the original, given value when given a non-String value', () => { + it('should return the original, given value when given a non-String value or non-String mark', () => { expect(smartTruncate(1000, 3)).to.equal(1000); expect(smartTruncate(undefined, 3)).to.equal(undefined); expect(smartTruncate(null, 3)).to.equal(null); + expect(smartTruncate('I am so tired', 3, {mark: null})).to.equal('I am so tired'); }); // ref: https://github.com/millerized/smart-truncate/issues/7 @@ -67,17 +68,44 @@ describe('smartTruncate(string, length[, position])', () => { const str = 'abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz'; const length = 50; const ellipsisOffset = 1; + const lastCharIndex = (length - 1); for (var i = length; i > -1; i--) { - const expectedIndex = (i >= (length - ellipsisOffset)) - ? (length - 1) + const expectedIndex = (i >= lastCharIndex) + ? lastCharIndex : i; - const truncated = smartTruncate(str, length, i); + const truncated = smartTruncate(str, length, {position: i}); const resultIndex = truncated.indexOf('…'); expect(resultIndex).to.equal(expectedIndex); expect(truncated.length).to.equal(length) } }); + + // ref: https://github.com/millerized/smart-truncate/issues/5 + it('should return truncated string using a custom mark given instead of the default ellipsis', () => { + const expected = 'abc—xyz'; + + const result = smartTruncate('abcdefghijklmnopqrstuvwxyz', 7, { + position: 3, + mark: '—', + }); + + expect(result).to.equal(expected); + expect(result.length).to.equal(expected.length); + }); + + // ref: https://github.com/millerized/smart-truncate/issues/5 + it('should return truncated string using a long custom mark given instead of the default ellipsis', () => { + const expected = 'abc***xyz'; + + const result = smartTruncate('abcdefghijklmnopqrstuvwxyz', 9, { + position: 3, + mark: '***', + }); + + expect(result).to.equal(expected); + expect(result.length).to.equal(expected.length); + }); });