Parse a single ANSI escape sequence.
110{
112 if (seq_len == 0)
113 return 0;
114
115 if (dry_run || !ansi)
116 return seq_len;
117
118 int pos = 2;
119
120 while (pos < seq_len)
121 {
122 if ((buf[pos] == '0') && isdigit(buf[pos + 1]))
123 {
124 pos++;
125 }
127 {
129 pos += 2;
130 }
132 {
133 ansi->
attrs |= A_BOLD;
134 pos += 2;
135 }
136 else if ((buf[pos] ==
'2') && isdigit(buf[pos + 1]) &&
ansi_is_end_char(buf[pos + 2]))
137 {
138 char digit = buf[pos + 1];
139 pos += 3;
141 {
142 ansi->
attrs &= ~A_BOLD;
143 }
144 else if (
digit ==
'3')
145 {
146 ansi->
attrs &= ~A_ITALIC;
147 }
148 else if (
digit ==
'4')
149 {
150 ansi->
attrs &= ~A_UNDERLINE;
151 }
152 else if (
digit ==
'5')
153 {
154 ansi->
attrs &= ~A_BLINK;
155 }
156 else if (
digit ==
'7')
157 {
158 ansi->
attrs &= ~A_REVERSE;
159 }
160 }
162 {
164 pos += 2;
165 }
166 else if (buf[pos] == '3')
167 {
169
170
171 if ((buf[pos + 1] >=
'0') && (buf[pos + 1] <
'8') &&
ansi_is_end_char(buf[pos + 2]))
172 {
173 elem->
color = buf[pos + 1] -
'0';
175 pos += 3;
176 }
177 else if (buf[pos + 1] == '8')
178 {
180 {
181
182 char *end = NULL;
183 unsigned long value = strtoul(buf + pos + 5, &end, 10);
185 {
188 pos += end - &buf[pos];
189 }
190 else
191 {
192 return 0;
193 }
194 }
196 {
197
198 long r = -1;
199 long g = -1;
200 long b = -1;
201 char *end = NULL;
202 unsigned long value = 0;
203 pos += 5;
204
205 value = strtoul(buf + pos, &end, 10);
206 if ((value > 255) || !end || (end[0] != ';'))
207 {
208 return 0;
209 }
210 r = value;
211 pos += end - &buf[pos] + 1;
212
213 value = strtoul(buf + pos, &end, 10);
214 if ((value > 255) || !end || (end[0] != ';'))
215 {
216 return 0;
217 }
218 g = value;
219 pos += end - &buf[pos] + 1;
220
221 value = strtoul(buf + pos, &end, 10);
222 if ((value > 255) || !end || (end[0] != 'm'))
223 {
224 return 0;
225 }
226 b = value;
227 pos += end - &buf[pos] + 1;
228
229 elem->
color = (r << 16) + (g << 8) + (b << 0);
231 }
232 else
233 {
234 return pos;
235 }
236 }
238 {
239
242 pos += 2;
243 }
244 else
245 {
246 return 0;
247 }
248 }
250 {
251 ansi->
attrs |= A_UNDERLINE;
252 pos += 2;
253 }
254 else if (buf[pos] == '4')
255 {
257
258
259 if ((buf[pos + 1] >=
'0') && (buf[pos + 1] <
'8') &&
ansi_is_end_char(buf[pos + 2]))
260 {
261 elem->
color = buf[pos + 1] -
'0';
263 pos += 3;
264 }
265 else if (buf[pos + 1] == '8')
266 {
268 {
269
270 char *end = NULL;
271 unsigned long value = strtoul(buf + pos + 5, &end, 10);
273 {
276 pos += end - &buf[pos];
277 }
278 else
279 {
280 return 0;
281 }
282 }
284 {
285
286 long r = -1;
287 long g = -1;
288 long b = -1;
289 char *end = NULL;
290 unsigned long value = 0;
291 pos += 5;
292
293 value = strtoul(buf + pos, &end, 10);
294 if ((value > 255) || !end || (end[0] != ';'))
295 {
296 return 0;
297 }
298 r = value;
299 pos += end - &buf[pos] + 1;
300
301 value = strtoul(buf + pos, &end, 10);
302 if ((value > 255) || !end || (end[0] != ';'))
303 {
304 return 0;
305 }
306 g = value;
307 pos += end - &buf[pos] + 1;
308
309 value = strtoul(buf + pos, &end, 10);
310 if ((value > 255) || !end || (end[0] != 'm'))
311 {
312 return 0;
313 }
314 b = value;
315 pos += end - &buf[pos] + 1;
316
317 elem->
color = (r << 16) + (g << 8) + (b << 0);
319 }
320 else
321 {
322 return pos;
323 }
324 }
326 {
327
330 pos += 2;
331 }
332 else
333 {
334 return 0;
335 }
336 }
338 {
339 ansi->
attrs |= A_BLINK;
340 pos += 2;
341 }
343 {
344 ansi->
attrs |= A_REVERSE;
345 pos += 2;
346 }
347 else if (buf[pos] == ';')
348 {
349 pos++;
350 }
351 else
352 {
353 while ((pos < seq_len) && (buf[pos] != ';'))
354 pos++;
355 }
356 }
357
358 return pos;
359}
@ CT_SIMPLE
Simple colour, e.g. "Red".
@ CT_PALETTE
Palette colour, e.g. "color207".
@ CT_RGB
True colour, e.g. "#11AAFF".
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.