Skip to content

Commit 4566fcc

Browse files
kukawskikvz
authored andcommitted
Fix issue locutusjs#327 Improved compatibility with PHP's wordwrap (locutusjs#328)
* Fix issue locutusjs#327 Improved compatibility with PHP's wordwrap Improved compatilibity with PHP's wordwrap Made the code a little more readable * Fix lint issue
1 parent 8016ac3 commit 4566fcc

File tree

1 file changed

+66
-21
lines changed

1 file changed

+66
-21
lines changed

src/php/strings/wordwrap.js

Lines changed: 66 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,39 +7,84 @@ module.exports = function wordwrap (str, intWidth, strBreak, cut) {
77
// revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
88
// bugfixed by: Michael Grier
99
// bugfixed by: Feras ALHAEK
10-
// note 1: It would be great if this function could be split up to have
11-
// note 1: smaller line lengths, less ternary operators, and more readable variable names
10+
// improved by: Rafał Kukawski (http://kukawski.net)
1211
// example 1: wordwrap('Kevin van Zonneveld', 6, '|', true)
13-
// returns 1: 'Kevin |van |Zonnev|eld'
12+
// returns 1: 'Kevin|van|Zonnev|eld'
1413
// example 2: wordwrap('The quick brown fox jumped over the lazy dog.', 20, '<br />\n')
15-
// returns 2: 'The quick brown fox <br />\njumped over the lazy<br />\n dog.'
14+
// returns 2: 'The quick brown fox<br />\njumped over the lazy<br />\ndog.'
1615
// example 3: wordwrap('Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.')
17-
// returns 3: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod \ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim \nveniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea \ncommodo consequat.'
16+
// returns 3: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim\nveniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea\ncommodo consequat.'
1817

19-
var m = ((arguments.length >= 2) ? arguments[1] : 75)
20-
var b = ((arguments.length >= 3) ? arguments[2] : '\n')
21-
var c = ((arguments.length >= 4) ? arguments[3] : false)
18+
intWidth = arguments.length >= 2 ? +intWidth : 75
19+
strBreak = arguments.length >= 3 ? '' + strBreak : '\n'
20+
cut = arguments.length >= 4 ? !!cut : false
2221

23-
var i, j, l, s, r
22+
var i, j, line
2423

2524
str += ''
2625

27-
if (m < 1) {
26+
if (intWidth < 1) {
2827
return str
2928
}
3029

31-
for (i = -1, l = (r = str.split(/\r\n|\n|\r/)).length; ++i < l; r[i] += s) {
32-
// @todo: Split this up over many more lines and more semantic variable names
33-
// so it becomes readable
34-
for (s = r[i], r[i] = '';
35-
s.length > m;
36-
r[i] += s.slice(0, j) + ((s = s.slice(j)).length ? b : '')) {
37-
j = c === 2 || (j = s.slice(0, m + 1).match(/\S*(\s)?$/))[1]
38-
? m
39-
: j.input.length - j[0].length || c === true && m ||
40-
j.input.length + (j = s.slice(m).match(/^\S*/))[0].length
30+
var reLineBreaks = /\r\n|\n|\r/
31+
var reBeginningUntilFirstWhitespace = /^\S*/
32+
var reLastCharsWithOptionalTrailingWhitespace = /\S*(\s)?$/
33+
34+
var lines = str.split(reLineBreaks)
35+
var l = lines.length
36+
var match
37+
38+
// for each line of text
39+
for (i = 0; i < l; lines[i++] += line) {
40+
line = lines[i]
41+
lines[i] = ''
42+
43+
while (line.length > intWidth) {
44+
// get slice of length one char above limit
45+
var slice = line.slice(0, intWidth + 1)
46+
47+
// remove leading whitespace from rest of line to parse
48+
var ltrim = 0
49+
// remove trailing whitespace from new line content
50+
var rtrim = 0
51+
52+
match = slice.match(reLastCharsWithOptionalTrailingWhitespace)
53+
54+
// if the slice ends with whitespace
55+
if (match[1]) {
56+
// then perfect moment to cut the line
57+
j = intWidth
58+
ltrim = 1
59+
} else {
60+
// otherwise cut at previous whitespace
61+
j = slice.length - match[0].length
62+
63+
if (j) {
64+
rtrim = 1
65+
}
66+
67+
// but if there is no previous whitespace
68+
// and cut is forced
69+
// cut just at the defined limit
70+
if (!j && cut && intWidth) {
71+
j = intWidth
72+
}
73+
74+
// if cut wasn't forced
75+
// cut at next possible whitespace after the limit
76+
if (!j) {
77+
var charsUntilNextWhitespace = (line.slice(intWidth).match(reBeginningUntilFirstWhitespace) || [''])[0]
78+
79+
j = slice.length + charsUntilNextWhitespace.length
80+
}
81+
}
82+
83+
lines[i] += line.slice(0, j - rtrim)
84+
line = line.slice(j + ltrim)
85+
lines[i] += line.length ? strBreak : ''
4186
}
4287
}
4388

44-
return r.join('\n')
89+
return lines.join('\n')
4590
}

0 commit comments

Comments
 (0)