18
18
*/
19
19
class AnsiToHtmlConverter
20
20
{
21
+ /**
22
+ * @var array<string, string>
23
+ */
21
24
protected array $ inlineColors ;
25
+
26
+ /**
27
+ * @var array<string>
28
+ */
22
29
protected array $ colorNames ;
23
30
24
31
public function __construct (
@@ -36,24 +43,25 @@ public function __construct(
36
43
37
44
public function convert (string $ text ): string
38
45
{
39
- // remove cursor movement sequences
40
- $ text = preg_replace ('#\e\[(K|s|u|2J|2K|\d+(A|B|C|D|E|F|G|J|K|S|T)|\d+;\d+(H|f))# ' , '' , $ text );
41
- // remove character set sequences
42
- $ text = preg_replace ('#\e(\(|\))(A|B|[0-2])# ' , '' , $ text );
43
-
44
- $ text = htmlspecialchars ($ text , \PHP_VERSION_ID >= 50400 ? \ENT_QUOTES | \ENT_SUBSTITUTE : \ENT_QUOTES , $ this ->charset );
46
+ $ text = preg_replace ([
47
+ // remove cursor movement sequences
48
+ '#\e\[(K|s|u|2J|2K|\d+(A|B|C|D|E|F|G|J|K|S|T)|\d+;\d+(H|f))# ' ,
49
+ // remove character set sequences
50
+ '#\e(\(|\))(A|B|[0-2])# ' ,
51
+ // remove carriage return
52
+ '#^.*\r(?!\n)#m ' ,
53
+ ], '' , $ text ) ?? '' ;
45
54
46
- // carriage return
47
- $ text = preg_replace ('#^.*\r(?!\n)#m ' , '' , $ text );
55
+ $ text = htmlspecialchars ($ text , \ENT_QUOTES | \ENT_SUBSTITUTE , $ this ->charset );
48
56
49
57
$ tokens = $ this ->tokenize ($ text );
50
58
51
59
// a backspace remove the previous character but only from a text token
52
60
foreach ($ tokens as $ i => $ token ) {
53
- if ('backspace ' == $ token [0 ]) {
61
+ if ('backspace ' === $ token [0 ]) {
54
62
$ j = $ i ;
55
63
while (--$ j >= 0 ) {
56
- if ('text ' == $ tokens [$ j ][0 ] && '' !== $ tokens [$ j ][1 ]) {
64
+ if ('text ' === $ tokens [$ j ][0 ] && '' !== $ tokens [$ j ][1 ]) {
57
65
$ tokens [$ j ][1 ] = substr ($ tokens [$ j ][1 ], 0 , -1 );
58
66
59
67
break ;
@@ -64,9 +72,9 @@ public function convert(string $text): string
64
72
65
73
$ html = '' ;
66
74
foreach ($ tokens as $ token ) {
67
- if ('text ' == $ token [0 ]) {
75
+ if ('text ' === $ token [0 ]) {
68
76
$ html .= $ token [1 ];
69
- } elseif ('color ' == $ token [0 ]) {
77
+ } elseif ('color ' === $ token [0 ]) {
70
78
$ html .= $ this ->convertAnsiToColor ($ token [1 ]);
71
79
}
72
80
}
@@ -78,9 +86,7 @@ public function convert(string $text): string
78
86
}
79
87
80
88
// remove empty span
81
- $ html = preg_replace ('#<span[^>]*></span># ' , '' , $ html );
82
-
83
- return $ html ;
89
+ return preg_replace ('#<span[^>]*></span># ' , '' , $ html ) ?? '' ;
84
90
}
85
91
86
92
public function getTheme (): Theme
@@ -95,7 +101,7 @@ protected function convertAnsiToColor(string $ansi): string
95
101
$ as = '' ; // inline styles
96
102
$ cs = '' ; // css classes
97
103
$ hi = false ; // high intensity
98
- if ('0 ' != $ ansi && '' != $ ansi ) {
104
+ if ('0 ' !== $ ansi && '' != = $ ansi ) {
99
105
$ options = explode ('; ' , $ ansi );
100
106
101
107
foreach ($ options as $ key => $ option ) {
@@ -109,19 +115,21 @@ protected function convertAnsiToColor(string $ansi): string
109
115
$ hi = true ;
110
116
} elseif ($ option >= 100 && $ option < 108 ) {
111
117
$ bg = $ option - 90 ;
112
- } elseif (39 == $ option ) {
118
+ } elseif (39 === $ option ) {
113
119
$ fg = 7 ;
114
- } elseif (49 == $ option ) {
120
+ } elseif (49 === $ option ) {
115
121
$ bg = 0 ;
116
122
} elseif ($ option >= 22 && $ option < 30 ) { // 21 has varying effects, best to ignored it
117
123
$ unset = $ option - 20 ;
118
124
119
125
foreach ($ options as $ i => $ v ) {
120
- if ($ v == $ unset ) {
126
+ $ v = (int ) $ v ;
127
+
128
+ if ($ v === $ unset ) {
121
129
unset($ options [$ i ]);
122
130
}
123
131
124
- if (2 == $ unset && 1 == $ v ) { // 22 also unsets bold
132
+ if (2 === $ unset && 1 = == $ v ) { // 22 also unsets bold
125
133
unset($ options [$ i ]);
126
134
}
127
135
@@ -171,6 +179,11 @@ protected function convertAnsiToColor(string $ansi): string
171
179
}
172
180
}
173
181
182
+ /**
183
+ * Tokenizes the given text into an array of tokens.
184
+ *
185
+ * @return list<array<int, string>>
186
+ */
174
187
protected function tokenize (string $ text ): array
175
188
{
176
189
$ tokens = [];
@@ -184,7 +197,7 @@ protected function tokenize(string $text): array
184
197
}
185
198
186
199
foreach (explode ('; ' , $ matches [1 ][$ i ][0 ]) as $ code ) {
187
- if ('0 ' == $ code || '' == $ code ) {
200
+ if ('0 ' === $ code || '' = == $ code ) {
188
201
$ codes = [];
189
202
} else {
190
203
// remove existing occurrence to avoid processing duplicate styles
@@ -196,7 +209,7 @@ protected function tokenize(string $text): array
196
209
$ codes [] = $ code ;
197
210
}
198
211
199
- $ tokens [] = ["\x08" == $ match [0 ] ? 'backspace ' : 'color ' , implode ('; ' , $ codes )];
212
+ $ tokens [] = ["\x08" === $ match [0 ] ? 'backspace ' : 'color ' , implode ('; ' , $ codes )];
200
213
$ offset = $ match [1 ] + \strlen ($ match [0 ]);
201
214
}
202
215
0 commit comments