Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
rudashi committed Jan 28, 2024
2 parents be97415 + bb4dde2 commit 4506a06
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/Str.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import {
ucfirst,
ucsplit,
wordCount,
wordWrap,
preg_quote,
ExcerptOptions,
} from './methods';
Expand Down Expand Up @@ -118,6 +119,7 @@ export const Str = {
length,
limit,
lower,
wordWrap,
words,
markdown: (string: string, options: MarkdownConfiguration = defaultConfiguration): string => {
options = {...defaultConfiguration, ...options};
Expand Down
6 changes: 6 additions & 0 deletions src/Stringable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,12 @@ export class Stringable {
return this;
}

public wordWrap = (width: number = 75, breaks: string = "\n", cut: boolean = false): this => {
this._value = Str.wordWrap(this._value, width, breaks, cut);

return this;
}

public wrap = (before: string, after?: string): this => {
this._value = Str.wrap(this._value, before, after);

Expand Down
35 changes: 35 additions & 0 deletions src/methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,41 @@ export const wrap = (value: string, before: string, after?: string): string => {
return before + value + (after ?? before);
}

export const wordWrap = (str: string, width: number = 75, breakChar: string = "\n", cut: boolean = false): string => {
if (str === '') {
return str
}

let pattern = `(?![^\\n]{1,${width}}$)([^\\n]{1,${width}})\\s`;

if (cut) {
let result = '';
let line = '';

for (const word of str.split(/\s+/)) {
if (word.length < width) {
if ((line + word + ' ').length > width) {
line = line.trimEnd() + breakChar
}

line += word + ' '
} else {
if (line !== '' && !line.endsWith(breakChar)) {
line = line.trimEnd() + breakChar
}

line += word.replace(new RegExp(`.{1,${width}}`, 'gu'), match => match + breakChar);
}

result = line;
}

return result.slice(0, breakChar.length * -1);
}

return str.replace(new RegExp(pattern, 'gu'), '$1' + breakChar);
}

export const is = (pattern: string | Array<string | null>, value: string): boolean => {
pattern = pattern instanceof Array ? pattern : [pattern];

Expand Down
31 changes: 31 additions & 0 deletions tests/wordWrap.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use strict';

const {Stringable} = require('../src/Stringable');
const {Str} = require('../src/Str');
const {wordWrap} = require('../src/methods');

it('returns a string wrapped to a given number of characters', () => {
expect(Stringable.of('The quick brown fox jumped over the lazy dog.').wordWrap(20, "<br />\n").toString())
.toBe("The quick brown fox<br />\njumped over the lazy<br />\ndog.");

expect(Stringable.of('Hello World').wordWrap(3, '<br />').toString())
.toBe('Hello<br />World');

expect(Stringable.of('A very long woooooooooooord.').wordWrap(8, '<br />', true).toString())
.toBe('A very<br />long<br />wooooooo<br />ooooord.');

expect(Stringable.of('A very long woooooooooooooooooord and something').wordWrap(8, '<br />', false).toString())
.toBe('A very<br />long<br />woooooooooooooooooord<br />and<br />something');

expect(Stringable.of('Hello World').wordWrap(3, '<br />', true).toString())
.toBe('Hel<br />lo<br />Wor<br />ld');

expect(Stringable.of('❤Multi Byte☆❤☆❤☆❤').wordWrap(3, '<br />').toString())
.toBe('❤Multi<br />Byte☆❤☆❤☆❤');

expect(Str.wordWrap('❤Multi Byte☆❤☆❤☆❤', 3, '<br />'))
.toBe('❤Multi<br />Byte☆❤☆❤☆❤');

expect(wordWrap('❤Multi Byte☆❤☆❤☆❤',3, '<br />'))
.toBe('❤Multi<br />Byte☆❤☆❤☆❤');
});

0 comments on commit 4506a06

Please sign in to comment.