diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..45083f3 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,19 @@ +name: Publish Package to npmjs +on: + release: + types: [published] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + # Setup .npmrc file to publish to npm + - uses: actions/setup-node@v3 + with: + node-version: '18.x' + registry-url: 'https://registry.npmjs.org' + - run: npm install + - run: npm run test + - run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.verb.md b/.verb.md index 270b02c..8163c38 100644 --- a/.verb.md +++ b/.verb.md @@ -41,7 +41,7 @@ wrap(str, {width: 60}); Type: `String` -Default: ` ` (two spaces) +Default: `` (none) The string to use at the beginning of each line. diff --git a/README.md b/README.md index 88b9684..804c750 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ > Wrap words to a specified length. +Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support. + ## Install Install with [npm](https://www.npmjs.com/): @@ -50,7 +52,7 @@ wrap(str, {width: 60}); Type: `String` -Default: `` (two spaces) +Default: `` (none) The string to use at the beginning of each line. @@ -123,31 +125,26 @@ wrap(str, {cut: true}); ## About -### Related projects +
+Contributing -* [common-words](https://www.npmjs.com/package/common-words): Updated list (JSON) of the 100 most common words in the English language. Useful for… [more](https://github.com/jonschlinkert/common-words) | [homepage](https://github.com/jonschlinkert/common-words "Updated list (JSON) of the 100 most common words in the English language. Useful for excluding these words from arrays.") -* [shuffle-words](https://www.npmjs.com/package/shuffle-words): Shuffle the words in a string and optionally the letters in each word using the… [more](https://github.com/jonschlinkert/shuffle-words) | [homepage](https://github.com/jonschlinkert/shuffle-words "Shuffle the words in a string and optionally the letters in each word using the Fisher-Yates algorithm. Useful for creating test fixtures, benchmarking samples, etc.") -* [unique-words](https://www.npmjs.com/package/unique-words): Return the unique words in a string or array. | [homepage](https://github.com/jonschlinkert/unique-words "Return the unique words in a string or array.") -* [wordcount](https://www.npmjs.com/package/wordcount): Count the words in a string. Support for english, CJK and Cyrillic. | [homepage](https://github.com/jonschlinkert/wordcount "Count the words in a string. Support for english, CJK and Cyrillic.") +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). -### Contributing +
-Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). +
+Running Tests -### Contributors +Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: + +```sh +$ npm install && npm test +``` -| **Commits** | **Contributor** | -| --- | --- | -| 43 | [jonschlinkert](https://github.com/jonschlinkert) | -| 2 | [lordvlad](https://github.com/lordvlad) | -| 2 | [hildjj](https://github.com/hildjj) | -| 1 | [danilosampaio](https://github.com/danilosampaio) | -| 1 | [2fd](https://github.com/2fd) | -| 1 | [toddself](https://github.com/toddself) | -| 1 | [wolfgang42](https://github.com/wolfgang42) | -| 1 | [zachhale](https://github.com/zachhale) | +
-### Building docs +
+Building docs _(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_ @@ -157,26 +154,48 @@ To generate the readme, run the following command: $ npm install -g verbose/verb#dev verb-generate-readme && verb ``` -### Running tests +
-Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: +### Related projects -```sh -$ npm install && npm test -``` +You might also be interested in these projects: + +* [common-words](https://www.npmjs.com/package/common-words): Updated list (JSON) of the 100 most common words in the English language. Useful for… [more](https://github.com/jonschlinkert/common-words) | [homepage](https://github.com/jonschlinkert/common-words "Updated list (JSON) of the 100 most common words in the English language. Useful for excluding these words from arrays.") +* [shuffle-words](https://www.npmjs.com/package/shuffle-words): Shuffle the words in a string and optionally the letters in each word using the… [more](https://github.com/jonschlinkert/shuffle-words) | [homepage](https://github.com/jonschlinkert/shuffle-words "Shuffle the words in a string and optionally the letters in each word using the Fisher-Yates algorithm. Useful for creating test fixtures, benchmarking samples, etc.") +* [unique-words](https://www.npmjs.com/package/unique-words): Returns an array of unique words, or the number of occurrences of each word in… [more](https://github.com/jonschlinkert/unique-words) | [homepage](https://github.com/jonschlinkert/unique-words "Returns an array of unique words, or the number of occurrences of each word in a string or list.") +* [wordcount](https://www.npmjs.com/package/wordcount): Count the words in a string. Support for english, CJK and Cyrillic. | [homepage](https://github.com/jonschlinkert/wordcount "Count the words in a string. Support for english, CJK and Cyrillic.") + +### Contributors + +| **Commits** | **Contributor** | +| --- | --- | +| 47 | [jonschlinkert](https://github.com/jonschlinkert) | +| 7 | [OlafConijn](https://github.com/OlafConijn) | +| 2 | [aashutoshrathi](https://github.com/aashutoshrathi) | +| 2 | [doowb](https://github.com/doowb) | +| 2 | [lordvlad](https://github.com/lordvlad) | +| 2 | [hildjj](https://github.com/hildjj) | +| 1 | [danilosampaio](https://github.com/danilosampaio) | +| 1 | [2fd](https://github.com/2fd) | +| 1 | [leonard-thieu](https://github.com/leonard-thieu) | +| 1 | [mohd-akram](https://github.com/mohd-akram) | +| 1 | [toddself](https://github.com/toddself) | +| 1 | [wolfgang42](https://github.com/wolfgang42) | +| 1 | [zachhale](https://github.com/zachhale) | ### Author **Jon Schlinkert** -* [github/jonschlinkert](https://github.com/jonschlinkert) -* [twitter/jonschlinkert](https://twitter.com/jonschlinkert) +* [GitHub Profile](https://github.com/jonschlinkert) +* [Twitter Profile](https://twitter.com/jonschlinkert) +* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert) ### License -Copyright © 2017, [Jon Schlinkert](https://github.com/jonschlinkert). +Copyright © 2023, [Jon Schlinkert](https://github.com/jonschlinkert). Released under the [MIT License](LICENSE). *** -_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on June 02, 2017._ \ No newline at end of file +_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on July 18, 2023._ \ No newline at end of file diff --git a/index.d.ts b/index.d.ts index 54ee5f2..1acd425 100644 --- a/index.d.ts +++ b/index.d.ts @@ -16,7 +16,7 @@ declare namespace wrap { /** * The string to use at the beginning of each line. - * @default ´ ´ (two spaces) + * @default ´´ (none) */ indent?: string; @@ -47,4 +47,4 @@ declare namespace wrap { */ cut?: boolean; } -} \ No newline at end of file +} diff --git a/index.js b/index.js index 45373c6..4e4dcaa 100644 --- a/index.js +++ b/index.js @@ -1,10 +1,25 @@ /*! * word-wrap * - * Copyright (c) 2014-2017, Jon Schlinkert. + * Copyright (c) 2014-2023, Jon Schlinkert. * Released under the MIT License. */ +function trimEnd(str) { + let lastCharPos = str.length - 1; + let lastChar = str[lastCharPos]; + while(lastChar === ' ' || lastChar === '\t') { + lastChar = str[--lastCharPos]; + } + return str.substring(0, lastCharPos + 1); +} + +function trimTabAndSpaces(str) { + const lines = str.split('\n'); + const trimmedLines = lines.map((line) => trimEnd(line)); + return trimmedLines.join('\n'); +} + module.exports = function(str, options) { options = options || {}; if (str == null) { @@ -14,7 +29,7 @@ module.exports = function(str, options) { var width = options.width || 50; var indent = (typeof options.indent === 'string') ? options.indent - : ' '; + : ''; var newline = options.newline || '\n' + indent; var escape = typeof options.escape === 'function' @@ -36,7 +51,7 @@ module.exports = function(str, options) { }).join(newline); if (options.trim === true) { - result = result.replace(/[ \t]*$/gm, ''); + result = trimTabAndSpaces(result); } return result; }; diff --git a/package.json b/package.json index 6f8f633..d3e4401 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "word-wrap", "description": "Wrap words to a specified length.", - "version": "1.2.3", + "version": "1.2.4", "homepage": "https://github.com/jonschlinkert/word-wrap", "author": "Jon Schlinkert (https://github.com/jonschlinkert)", "contributors": [ diff --git a/test.js b/test.js index aff353e..e60fee8 100644 --- a/test.js +++ b/test.js @@ -8,11 +8,11 @@ var str = 'A project without documentation is like a project that doesn\'t exist describe('wrap', function () { it('should use defaults to wrap words in the given string:', function () { - assert.equal(wrap(str), ' A project without documentation is like a project \n that doesn\'t exist. Verb solves this by making it \n dead simple to generate project documentation, \n using simple markdown templates, with zero \n configuration required. '); + assert.equal(wrap(str), 'A project without documentation is like a project \nthat doesn\'t exist. Verb solves this by making it \ndead simple to generate project documentation, \nusing simple markdown templates, with zero \nconfiguration required. '); }); it('should wrap to the specified width:', function () { - assert.equal(wrap(str, {width: 40}), ' A project without documentation is like \n a project that doesn\'t exist. Verb \n solves this by making it dead simple to \n generate project documentation, using \n simple markdown templates, with zero \n configuration required. '); + assert.equal(wrap(str, {width: 40}), 'A project without documentation is like \na project that doesn\'t exist. Verb \nsolves this by making it dead simple to \ngenerate project documentation, using \nsimple markdown templates, with zero \nconfiguration required. '); }); it('should indent the specified amount:', function () { @@ -20,18 +20,22 @@ describe('wrap', function () { }); it('should use the given string for newlines:', function () { - assert.equal(wrap(str, {newline: '\n\n-'}), ' A project without documentation is like a project \n\n-that doesn\'t exist. Verb solves this by making it \n\n-dead simple to generate project documentation, \n\n-using simple markdown templates, with zero \n\n-configuration required. '); + assert.equal(wrap(str, {newline: '\n\n-'}), 'A project without documentation is like a project \n\n-that doesn\'t exist. Verb solves this by making it \n\n-dead simple to generate project documentation, \n\n-using simple markdown templates, with zero \n\n-configuration required. '); }); it('should run the escape function on each line', function () { assert.equal( wrap(str, {escape: function(e) {return e.replace('\'', '\\\'')}}), - ' A project without documentation is like a project \n that doesn\\\'t exist. Verb solves this by making it \n dead simple to generate project documentation, \n using simple markdown templates, with zero \n configuration required. ' + 'A project without documentation is like a project \nthat doesn\\\'t exist. Verb solves this by making it \ndead simple to generate project documentation, \nusing simple markdown templates, with zero \nconfiguration required. ' ) }); it('should trim trailing whitespace:', function () { - assert.equal(wrap(str, {trim: true}), ' A project without documentation is like a project\n that doesn\'t exist. Verb solves this by making it\n dead simple to generate project documentation,\n using simple markdown templates, with zero\n configuration required.'); + assert.equal(wrap(str, {trim: true}), 'A project without documentation is like a project\nthat doesn\'t exist. Verb solves this by making it\ndead simple to generate project documentation,\nusing simple markdown templates, with zero\nconfiguration required.'); + }); + + it('should trim trailing whitespace (even for empty lines):', function () { + assert.equal(wrap("a \n\nb \n \nc\t", {trim: true}), 'a\n\nb\n\nc'); }); it('should handle strings with just newlines', function () { @@ -39,27 +43,27 @@ describe('wrap', function () { }); it('should handle newlines that occur at the same position as `options.width`', function () { - assert.equal(wrap('asdfg\nqwert', {width:5}), ' asdfg\n qwert'); - assert.equal(wrap('aaaaaa\nbbbbbb\ncccccc', {width:6}), ' aaaaaa\n bbbbbb\n cccccc'); + assert.equal(wrap('asdfg\nqwert', {width:5}), 'asdfg\nqwert'); + assert.equal(wrap('aaaaaa\nbbbbbb\ncccccc', {width:6}), 'aaaaaa\nbbbbbb\ncccccc'); }); it('should handle strings that break where there are multiple spaces', function() { - assert.equal(wrap('foo foo. bar', {width:8}), ' foo foo. \n bar'); - assert.equal(wrap('foo foo. bar', {width:8, trim: true}), ' foo foo.\n bar'); + assert.equal(wrap('foo foo. bar', {width:8}), 'foo foo. \nbar'); + assert.equal(wrap('foo foo. bar', {width:8, trim: true}), 'foo foo.\nbar'); }); it('should cut one long word', function() { - assert.equal(wrap('Supercalifragilisticexpialidocious', {width:24, cut:true}), ' Supercalifragilisticexpi\n alidocious'); + assert.equal(wrap('Supercalifragilisticexpialidocious', {width:24, cut:true}), 'Supercalifragilisticexpi\nalidocious'); }); it('should cut long words', function() { - assert.equal(wrap('Supercalifragilisticexpialidocious and Supercalifragilisticexpialidocious', {width:24, cut:true}), ' Supercalifragilisticexpi\n alidocious and Supercali\n fragilisticexpialidociou\n s'); + assert.equal(wrap('Supercalifragilisticexpialidocious and Supercalifragilisticexpialidocious', {width:24, cut:true}), 'Supercalifragilisticexpi\nalidocious and Supercali\nfragilisticexpialidociou\ns'); }); it('should wrap on zero space characters', function () { assert.equal( wrap('Supercalifragilistic\u200Bexpialidocious', {width: 24}), - ' Supercalifragilistic\u200B\n expialidocious' + 'Supercalifragilistic\u200B\nexpialidocious' ); }); });