Skip to content

Commit

Permalink
Merge 72994a8 into 324a096
Browse files Browse the repository at this point in the history
  • Loading branch information
millerized committed Jan 6, 2018
2 parents 324a096 + 72994a8 commit af4f61c
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 43 deletions.
21 changes: 12 additions & 9 deletions README.md
@@ -1,25 +1,28 @@
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_**<br>
&nbsp;&nbsp;&nbsp;&nbsp;A string with a minimum lenght of 4 characters.
&emsp;A string with a minimum length of 4 characters.

>**_length_**<br>
&nbsp;&nbsp;&nbsp;&nbsp;The length of the truncated result.
&emsp;The length of the truncated result.

>**_position_**<br>
&nbsp;&nbsp;&nbsp;&nbsp;Optional. The index of the ellipsis (zero based). Default is at the end.
>**_options_**<br>
>**_options.position_**<br>
&emsp;Optional. The index of the ellipsis (zero based). Default is at the end.<br>
>**_options.mark_**<br>
&emsp;Optional. The character[s] indicating omission. Default is an ellipsis "…".

#### Return value
>A new string truncated with an ellipsis.
Expand All @@ -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."`
Expand All @@ -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**:
Expand Down
33 changes: 21 additions & 12 deletions dist/smart-truncate.es5.js
Expand Up @@ -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;
Expand All @@ -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;
34 changes: 22 additions & 12 deletions 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;
Expand All @@ -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;
48 changes: 38 additions & 10 deletions src/smart-truncate.spec.js
Expand Up @@ -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);
});

Expand All @@ -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', () => {
Expand All @@ -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', () => {
Expand All @@ -56,28 +56,56 @@ 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
it('should assert the correct index of the given position and length of truncated result', () => {
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);
});
});

0 comments on commit af4f61c

Please sign in to comment.