Parse a single ANSI escape sequence.
108{
110 if (seq_len == 0)
111 return 0;
112
113 if (dry_run || !ansi)
114 return seq_len;
115
116 int pos = 2;
117
118 while (pos < seq_len)
119 {
121 {
122 pos++;
123 }
125 {
127 pos += 2;
128 }
130 {
131 ansi->
attrs |= A_BOLD;
132 pos += 2;
133 }
134 else if ((buf[pos] ==
'2') &&
mutt_isdigit(buf[pos + 1]) &&
136 {
137 char digit = buf[pos + 1];
138 pos += 3;
140 {
141 ansi->
attrs &= ~A_BOLD;
142 }
143 else if (
digit ==
'3')
144 {
146 }
147 else if (
digit ==
'4')
148 {
149 ansi->
attrs &= ~A_UNDERLINE;
150 }
151 else if (
digit ==
'5')
152 {
153 ansi->
attrs &= ~A_BLINK;
154 }
155 else if (
digit ==
'7')
156 {
157 ansi->
attrs &= ~A_REVERSE;
158 }
159 }
161 {
163 pos += 2;
164 }
165 else if (buf[pos] == '3')
166 {
168
169
170 if ((buf[pos + 1] >=
'0') && (buf[pos + 1] <
'8') &&
ansi_is_end_char(buf[pos + 2]))
171 {
172 elem->
color = buf[pos + 1] -
'0';
174 pos += 3;
175 }
176 else if (buf[pos + 1] == '8')
177 {
179 {
180
181 char *end = NULL;
182 unsigned long value = strtoul(buf + pos + 5, &end, 10);
184 {
187 pos += end - &buf[pos];
188 }
189 else
190 {
191 return 0;
192 }
193 }
195 {
196
197 long r = -1;
198 long g = -1;
199 long b = -1;
200 char *end = NULL;
201 unsigned long value = 0;
202 pos += 5;
203
204 value = strtoul(buf + pos, &end, 10);
205 if ((value > 255) || !end || (end[0] != ';'))
206 {
207 return 0;
208 }
209 r = value;
210 pos += end - &buf[pos] + 1;
211
212 value = strtoul(buf + pos, &end, 10);
213 if ((value > 255) || !end || (end[0] != ';'))
214 {
215 return 0;
216 }
217 g = value;
218 pos += end - &buf[pos] + 1;
219
220 value = strtoul(buf + pos, &end, 10);
221 if ((value > 255) || !end || (end[0] != 'm'))
222 {
223 return 0;
224 }
225 b = value;
226 pos += end - &buf[pos] + 1;
227
228 elem->
color = (r << 16) + (g << 8) + (b << 0);
230 }
231 else
232 {
233 return pos;
234 }
235 }
237 {
238
241 pos += 2;
242 }
243 else
244 {
245 return 0;
246 }
247 }
249 {
250 ansi->
attrs |= A_UNDERLINE;
251 pos += 2;
252 }
253 else if (buf[pos] == '4')
254 {
256
257
258 if ((buf[pos + 1] >=
'0') && (buf[pos + 1] <
'8') &&
ansi_is_end_char(buf[pos + 2]))
259 {
260 elem->
color = buf[pos + 1] -
'0';
262 pos += 3;
263 }
264 else if (buf[pos + 1] == '8')
265 {
267 {
268
269 char *end = NULL;
270 unsigned long value = strtoul(buf + pos + 5, &end, 10);
272 {
275 pos += end - &buf[pos];
276 }
277 else
278 {
279 return 0;
280 }
281 }
283 {
284
285 long r = -1;
286 long g = -1;
287 long b = -1;
288 char *end = NULL;
289 unsigned long value = 0;
290 pos += 5;
291
292 value = strtoul(buf + pos, &end, 10);
293 if ((value > 255) || !end || (end[0] != ';'))
294 {
295 return 0;
296 }
297 r = value;
298 pos += end - &buf[pos] + 1;
299
300 value = strtoul(buf + pos, &end, 10);
301 if ((value > 255) || !end || (end[0] != ';'))
302 {
303 return 0;
304 }
305 g = value;
306 pos += end - &buf[pos] + 1;
307
308 value = strtoul(buf + pos, &end, 10);
309 if ((value > 255) || !end || (end[0] != 'm'))
310 {
311 return 0;
312 }
313 b = value;
314 pos += end - &buf[pos] + 1;
315
316 elem->
color = (r << 16) + (g << 8) + (b << 0);
318 }
319 else
320 {
321 return pos;
322 }
323 }
325 {
326
329 pos += 2;
330 }
331 else
332 {
333 return 0;
334 }
335 }
337 {
338 ansi->
attrs |= A_BLINK;
339 pos += 2;
340 }
342 {
343 ansi->
attrs |= A_REVERSE;
344 pos += 2;
345 }
346 else if (buf[pos] == ';')
347 {
348 pos++;
349 }
350 else
351 {
352 while ((pos < seq_len) && (buf[pos] != ';'))
353 pos++;
354 }
355 }
356
357 return pos;
358}
@ CT_SIMPLE
Simple colour, e.g. "Red".
@ CT_PALETTE
Palette colour, e.g. "color207".
@ CT_RGB
True colour, e.g. "#11AAFF".
bool mutt_isdigit(int arg)
Wrapper for isdigit(3)
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
void ansi_color_reset(struct AnsiColor *ansi)
Reset an AnsiColor to uncoloured.
static bool ansi_is_end_char(char c)
Is this the end of a sequence?
int ansi_color_seq_length(const char *str)
Is this an ANSI escape sequence?
int attrs
Text attributes, e.g. A_BOLD.
struct ColorElement bg
Background colour.
struct ColorElement fg
Foreground colour.
enum ColorType type
Type of Colour.