-
-
Notifications
You must be signed in to change notification settings - Fork 73
/
Copy pathwrap.php
89 lines (78 loc) · 2.94 KB
/
wrap.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<?php
declare(strict_types=1);
namespace Psl\Str;
/**
* Wraps a string to a given number of characters.
*
* @param non-empty-string $break the line is broken using the optional break parameter
* @param bool $cut If the cut is set to true, the string is always wrapped at or before the specified width.
* so if you have a word that is larger than the given width, it is broken apart.
*
* @throws Exception\LogicException If $width is 0 and $cut is set to true.
*
* @return string the given string wrapped at the specified column
*
* @pure
*/
function wrap(
string $string,
int $width = 75,
string $break = "\n",
bool $cut = false,
Encoding $encoding = Encoding::Utf8,
): string {
if ('' === $string) {
return '';
}
if (0 === $width && $cut) {
throw new Exception\LogicException('Cannot force cut when width is zero.');
}
$string_length = length($string, $encoding);
$break_length = length($break, $encoding);
$result = '';
$last_start = 0;
$last_space = 0;
for ($current = 0; $current < $string_length; ++$current) {
$char = slice($string, $current, 1, $encoding);
$possible_break = $char;
if (1 !== $break_length) {
$possible_break = slice($string, $current, $break_length, $encoding);
}
if ($possible_break === $break) {
/** @psalm-suppress InvalidArgument - length is positive */
$result .= slice($string, $last_start, ($current - $last_start) + $break_length, $encoding);
$current += $break_length - 1;
$last_space = $current + 1;
$last_start = $last_space;
continue;
}
if (' ' === $char) {
$length = $current - $last_start;
if ($length >= $width) {
/** @psalm-suppress InvalidArgument - length is positive */
$result .= slice($string, $last_start, $length, $encoding) . $break;
$last_start = $current + 1;
}
$last_space = $current;
continue;
}
$length = $current - $last_start;
if ($length >= $width && $cut && $last_start >= $last_space) {
/** @psalm-suppress InvalidArgument - length is positive */
$result .= slice($string, $last_start, $length, $encoding) . $break;
$last_space = $current;
$last_start = $last_space;
continue;
}
if (($current - $last_start) >= $width && $last_start < $last_space) {
/** @psalm-suppress InvalidArgument - length is positive */
$result .= slice($string, $last_start, $last_space - $last_start, $encoding) . $break;
$last_start = ++$last_space;
}
}
if ($last_start !== $current) {
/** @psalm-suppress InvalidArgument - length is positive */
$result .= slice($string, $last_start, $current - $last_start, $encoding);
}
return $result;
}